11
votes

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’

2
What are you trying to do? It sounds like treating A as polymorphic is a wrong idea, since you won't be making use of that. - R. Martinho Fernandes
It's not about smart pointers, you are using polymorphism incorrectly. Replace public b member with virtual function (probably, get and set functions). - Alex F
I've simplified the classes. In their real form the polymorphism makes sense. - Medical physicist
Then it sounds like the simplified example is not representative of the real problem. - R. Martinho Fernandes

2 Answers

17
votes

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
5
votes
for(int i = 0; i < 10; i++) {
    auto bptr = make_shared<B>();
    v.push_back(bptr);
    bptr->b = 1;
};