Steven Lu
Steven Lu

Reputation: 43427

What is the correct way to access a derived class object in a base class pointer container?

I have a vector<boost::shared_ptr<Base>> object. I'm inserting an object of type Derived where Derived inherits Base like this: container.push_back(boost::shared_ptr<Base>(new Derived()));

I now want to call a function which takes a reference to a member of Derived, in order to modify this last entry I just inserted. This way, I don't end up creating a temporary instance of this Derived object. This is how I'm able to do it: func(static_cast<Derived*>(&*container.back())->member);

This looks really scary-ugly for me. But if I try to do func(static_cast<Derived>(*container.back()).member); instead, the compiler says I need to provide a ctor for Derived which takes the args (const Base&) in order to convert an instance of Base to an instance of Derived, which I don't need to do here... I just want to refer to my shared_ptr pointer as though it were a Derived* because I know it is because I just newed it.

Upvotes: 1

Views: 123

Answers (3)

Loki Astari
Loki Astari

Reputation: 264391

I would use dynamic_cast<> as the object being stored may not actually be of type Derived (it may be a Derived_2 also derived from Base).

func(dynamic_cast<Derived&>(*container.back()).member)

You can also cast to references to make it look slightly neater.

Note: dynamic_cast<>

  • if used to cast a pointer may return NULL
  • if used to cast a reference may throw std::bad_cast

Which is why I prefer to use dynamic_cast with references usually. But if you use it with a pointer be sure to check the result is not NULL before you use it.

Edit on the updated question:

But if I try to do func(static_cast(*container.back()).member);

You want a reference

static_cast<Derived&>
                  ^^^  Not the & here

This will stop it trying to call the constructor. If you static_cast<> to Derived it will try and create an object. What you really want is a reference.

Upvotes: 1

Henrik
Henrik

Reputation: 23324

You can use static_pointer_cast and dynamic_pointer_cast to cast between shared_ptrs:

shared_ptr<Derived> sp = static_pointer_cast<Derived>(container.back());

Upvotes: 0

Yakov Galka
Yakov Galka

Reputation: 72479

vector<boost::shared_ptr<Base>> container;

shared_ptr<Derived> ptr(new Derived());
container.push_back(ptr);
func(ptr->member);

No casts. No temporaries of Derived.

Upvotes: 3

Related Questions