dangerChihuahua007
dangerChihuahua007

Reputation: 20895

How do I implement abstract classes in C++ while allowing for subclass method calls?

I made a class called A that has a virtual method do_something:

class A {
  virtual int do_something() = 0;
}

B subclasses A:

class B {
  virtual int do_something() {
    return 42;
  }
}

Somewhere in my main function, I do this.

vector<A> arr;
arr.push_back(B());
int val = arr[0].do_something();

However, I get a compiler error complaining that do_something is a pure virtual function. I believe this is because I declared the vector to contain objects of type A, and A is an abstract class. The compiler thus doesn't know to look in class B to see if do_something is define.

Is there a way around this? Can I still store a vector of objects of different types (with a common superclass though that declares a common virtual function)?

Upvotes: 1

Views: 125

Answers (2)

Andy Prowl
Andy Prowl

Reputation: 126442

By declaring a vector this way:

vector<A> arr;

You are attempting to create a vector of objects of direct type A. Not only this would not allow you to store objects of type B in there (if A were not abstract, you would get slicing, which you certainly don't want), but it also fails to compile because no direct instances of A can exist.

What you want here is to store pointers to A (possibly smart pointers):

#include <memory> // For smart pointer classes

vector<shared_ptr<A>> arr;
arr.push_back(make_shared<B>());
int val = arr[0]->do_something();

Here I decided to use shared_ptr, assuming shared ownership, but if the only owner of the objects is the container arr, unique_ptr would be a better choice.

Eventually, if you really know what you are doing and you are ready to bear the hassle of automatic memory management, you could use raw pointers, but I discourage you from doing that (you would have to make sure you deallocate with delete every object you allocate with new):

vector<A*> arr;
arr.push_back(new B());
int val = arr[0]->do_something();

Upvotes: 4

billz
billz

Reputation: 45410

Is there a way around this? Can I still store a vector of objects of different types (with a common superclass though that declares a common virtual function)?

use smart pointer with std::vector

std::vector<std::unique<A>> arr;
arr.emplace_back(new B());

OR

arr.emplace_back(std::make_shared<B>());

Upvotes: 2

Related Questions