user2138149
user2138149

Reputation: 16533

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 newing and deleteing?

Edit: In 2015 I didn't know about polymorphism, if you are reading this question in 2022 it would be worth searching for some information about that.

Upvotes: 8

Views: 16835

Answers (2)

Ankit Acharya
Ankit Acharya

Reputation: 3111

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.

Upvotes: 17

Billy ONeal
Billy ONeal

Reputation: 106530

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.

Upvotes: 13

Related Questions