Getting a vector into a function that expects a vector<Base*>

后端 未结 9 1804
日久生厌
日久生厌 2020-11-29 07:11

Consider these classes.

class Base
{
   ...
};

class Derived : public Base
{
   ...
};

this function

void BaseFoo( std::ve         


        
相关标签:
9条回答
  • 2020-11-29 07:49

    Generally you would start with a container of base pointers, not the other way.

    0 讨论(0)
  • 2020-11-29 07:52

    They are unrelated types -- you can't.

    0 讨论(0)
  • 2020-11-29 07:53

    This problem occurs in programming languages that have mutable containers. You cannot pass around a mutable bag of apples as a bag of fruit because you cannot be sure that someone else does not put a lemon into that bag of fruit, after which it no longer qualifies as a bag of apples. If the bag of apples were not mutable, passing it around as a bag of fruit would be fine. Search for covariance/contravariance.

    0 讨论(0)
  • 2020-11-29 07:55

    Instead of passing the container object (vector<>), pass in begin and end iterators like the rest of the STL algorithms. The function that receives them will be templated, and it won't matter if you pass in Derived* or Base*.

    0 讨论(0)
  • 2020-11-29 07:56

    Taking Matt Price's answer from above, given that you know in advance what types you want to use with your function, you can declare the function template in the header file, and then add explicit instantiations for those types:

    // BaseFoo.h
    template<typename T>
    void BaseFoo( const std::vector<T*>& vec);
    
    // BaseFoo.cpp
    template<typename T>
    void BaseFoo( const std::vector<T*>& vec);
    {
     ...
    }
    
    // Explicit instantiation means no need for definition in the header file.
    template void BaseFoo<Base> ( const std::vector<Base*>& vec );
    template void BaseFoo<Derived> ( const std::vector<Derived*>& vec );
    
    0 讨论(0)
  • 2020-11-29 07:58

    vector<Base*> and vector<Derived*> are unrelated types, so you can't do this. This is explained in the C++ FAQ here.

    You need to change your variable from a vector<Derived*> to a vector<Base*> and insert Derived objects into it.

    Also, to avoid copying the vector unnecessarily, you should pass it by const-reference, not by value:

    void BaseFoo( const std::vector<Base*>& vec )
    {
        ...
    }
    

    Finally, to avoid memory leaks, and make your code exception-safe, consider using a container designed to handle heap-allocated objects, e.g:

    #include <boost/ptr_container/ptr_vector.hpp>
    boost::ptr_vector<Base> vec;
    

    Alternatively, change the vector to hold a smart pointer instead of using raw pointers:

    #include <memory>
    std::vector< std::shared_ptr<Base*> > vec;
    

    or

    #include <boost/shared_ptr.hpp>
    std::vector< boost::shared_ptr<Base*> > vec;
    

    In each case, you would need to modify your BaseFoo function accordingly.

    0 讨论(0)
提交回复
热议问题