Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 smart pointers and polymorphism

I'm rewriting an application using c++11 smart pointers.

I have a base class:

class A {};

And a derived class:

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

I have another class containing a vector with either A or B objects:

class C {
  public:
  vector<shared_ptr<A>> v;
};

I have no problem constructing C with A (base class) objects but how can I fill it with B (derived class) objects?

I'm trying this:

for(int i = 0; i < 10; i++) {
    v.push_back(make_shared<B>());
    v.back()->b = 1;
};  

And the compiler returns: error: ‘class A’ has no member named ‘b’

like image 912
Medical physicist Avatar asked Apr 02 '13 10:04

Medical physicist


People also ask

Is smart pointers C++ 11?

Introduction of Smart Pointers C++11 comes up with its own mechanism that's Smart Pointer. When the object is destroyed it frees the memory as well. So, we don't need to delete it as Smart Pointer does will handle it.

Do you need pointers for polymorphism?

(*) Genericity, the type of polymorphism provided by templates, doesn't need pointers nor references.

What is a polymorphic pointer?

Pointers to base class One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature.

Are smart pointers on the stack or heap?

As shown in the example, a smart pointer is a class template that you declare on the stack, and initialize by using a raw pointer that points to a heap-allocated object. After the smart pointer is initialized, it owns the raw pointer.


2 Answers

But how can I fill it with B (derived class) objects?

You are filling it with (pointers to) B objects. However, the pointers' static type refers to the base class A, so you cannot directly use these to access any members of the derived class.

In your simple example, you could simply keep hold of a pointer to B and use that:

std::shared_ptr<B> b = make_shared<B>();
b->b = 1;
v.push_back(b);

If you don't have access to the original pointer, then you will need some kind of polymorphism:

  • use static_cast<B*>(v.back().get()) if you know that all objects have type B
  • use a virtual function or dynamic_cast (which requires the base class to contain a virtual function to work) if the objects might have different types
like image 155
Mike Seymour Avatar answered Oct 11 '22 18:10

Mike Seymour


for(int i = 0; i < 10; i++) {
    auto bptr = make_shared<B>();
    v.push_back(bptr);
    bptr->b = 1;
};  
like image 23
Henrik Avatar answered Oct 11 '22 20:10

Henrik