Dom Farolino Dom Farolino - 1 year ago 52
C++ Question

Resize a std::vector<AbstractClass*>

It is my understanding that we can never instantiate an abstract class in

or equally an interface in
. This makes sense because we have "pure virtual" functions that provide no implementation, therefore we can only instantiate subclasses of this class/interface that adhere to the contract formed by the abstract class. Consider the following code:

#include <iostream>
#include <vector>

using namespace std;

class AbstractClass {
AbstractClass() {
cout << "Instantiating" << endl;

virtual void pureVirtualFunction() = 0;

void testMe() {
cout << "test" << endl;

int main() {
vector<AbstractClass*> v;
cout << v.size() << endl;
v[0]->pureVirtualFunction(); //segfault on my machine
return 0;

What baffles me when I run this on my computer is that I can actually resize the vector. I always thought that
instantiated some number of elements, thus calling each element's constructor but further research shows that the constructor is not actually called (also evident by my stdout not showing 100x "Instantiating" strings).

So if
allocates space for these new objects, and allows me to actually call methods on each of them, how are they not fully instantiated? I figured I couldn't even call
on a vector of abstract classes but I can, I assume because they are not fully initialized. Could someone explain what is happening here?


Brain fart..forgot that a vector of pointers, when resized, does not actually allocate
elements, as pointers can be created without allocated elements behind them, however...why can I still call a member function on a pointer to a class in which is not instantiated?

Answer Source

The other answers already say what's wrong with your code, I'm here to answer the edit:

however...why can I still call a member function on a pointer to a class in which is not instantiated?

You mean this part in particular:

  v[0]->pureVirtualFunction(); //segfault on my machine

Basically, because v[0] doesn't point to a valid object yet trying to call testMe() is already undefined behaviour.

The only reason it doesn't segfault is because you're (un)lucky that the compiler rewrote your code. Your body of the method testMe() doesn't require the *this object at all and thus the compiler will just replace it with a cout call. Because no attempt to access some invalid this pointer is made there is no segfault yet. Then, when calling the second method the compiler needs to check the vtable of an invalid this pointer, which causes the segfault. Don't ever rely on the behaviour of the testMe() working out, this is still undefined behaviour, anything can happen.