4

I have came from those questions:

They all suggested that I should use pointer or smart pointers instead.

As far as I know, Data are dynamically allocated in std::vector which means that there are pointers internally in the std::vector. So why I can not use abstract classes directly? why I have to use pointers(The one I specified) for pointers(the internally) in order to use abstract classes with std::vector. I know some features like std::vector::resize won't work. However, std::vector::reserve and std::back_inserter will solve the problem.

Community
  • 1
  • 1
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160

4 Answers4

6

As far as I know, Data are dynamically allocated in std::vector which means that there is pointers internally in the std::vector

That's absolutely right. However, the pointer (actually, one of two pointers in the very common implementation) points to an array of identically-sized elements of type T, not to a single element of T or its subtype. Essentially, the pointer is used to represent an array, not to refer to a class or its subclass.

That is why you need an extra level of indirection - elements of an array T[] are not capable of storing subclasses of T without object slicing.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
5

Data are dynamically allocated in std::vector which means that there is pointers internally in the std::vector

No, that's a misconception. std::vector allocates an array of instances internally, and you can't create an instance of an abstract class.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
2

While it is true that memory for std::vector is allocated dynamically, the fact is that in std::vector<T> objects of type T are stored as copies. And you simply cannot copy abstract classes.

For example, if you have a base class A, a derived class B, and a std::vector<A>. Then, if you try to stored an object of type B in that vector, it will be copied and stored as an A. That is, it will be spliced.

class A {};
class B: public A {};

int main()
{
    std::vector<A> as;
    B b;
    as.push_back(b); //<-- splice!!!
}

That, assuming that class A is copiable (and non-abstract). If it is abstract the compiler will save you the trouble and fail the declaration of the vector.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
0

In order to insert something into a vector, the template has to first instantiate the class (since it uses the copy constructor). Since this is not possible with an abstract class, you can't do it!

Source

gsamaras
  • 71,951
  • 46
  • 188
  • 305