简体   繁体   中英

C++ vector of base class objects

If I have a base class and a derived class, I can create a vector of base class pointers, if I want to group multiple base and/or derived classes together in a container.

Example:

class base
{
}

class derived : public base
{
}

std::vector<base*> group;

But is it possible to do the following?

std::vector<base> group;

ie: Without the pointers, which require new ing and delete ing?

A "yes"/"no" comment or more detailed explanation in an answer will suffice.

Yes you can use vector<base> & the compiler won't raise any error for this usage. However, the problem with vector<base> is that it fails to achieve polymorphism . See below :-

#include <iostream>
#include <vector>
using namespace std;

class base
{
    int x, id;
    static int i;
    public:
    base()
    {
        id = ++i;
        cout << "Base constructed: " << id << "\n";
    }
    base (const base &b)
    {
        id = ++i;
        cout << "Base copy constructed: " << id << "\n";
    }
    virtual int& getx()
    {
        cout << "Base getx() called\n";
        return x;
    }
    virtual ~base()
    {
        cout << "Base destroyed: " << id << "\n";
    }
};
int base :: i = 0; 

class derived : public base
{
    int x, id;
    static int j;
    public:
    derived()
    {
        id = ++j;
        cout << "Derived constructed: " << id << "\n";
    }
    derived (const derived& d)
    {
        id = ++j;
        cout << "Derived copy constructed: " << id << "\n";
    }
    virtual int& getx()
    {
        cout << "Derived getx() called\n";
        return x;
    }
    virtual ~derived()
    {
        cout << "Derived destroyed: " << id << "\n";
    }
};
int derived :: j = 0;

int main()
{
    vector<base> v;
    v.emplace_back(derived());
    v[0].getx() = 7;
    cout << "\n\n";
    for (int i=0; i<v.size(); ++i)
    cout << v[i].getx() <<"\n";
    cout << "\n\n";
    return 0;
}
/* Output :-
Base constructed: 1
Derived constructed: 1
Base copy constructed: 2
Derived destroyed: 1
Base destroyed: 1
Base getx() called


Base getx() called
7


Base destroyed: 2
*/

You can clearly see that although the object is of derived neither the copy constructor of derived is called nor getx() of the same. So the purpose of using vector<base> to achieve polymorphism is defeated. Hence you should never use vector<base> & rather prefer vectors of smart pointers or raw pointers.

You can't do vector<base> , but you can do vector<unique_ptr<base>> and avoid having to write new or delete manually. Use make_unique instead of new and delete gets handled for you automagically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM