Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ vector of base class objects

Tags:

c++

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.

like image 235
FreelanceConsultant Avatar asked Nov 29 '22 23:11

FreelanceConsultant


1 Answers

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.

like image 110
Ankit Acharya Avatar answered Dec 15 '22 22:12

Ankit Acharya