Reputation: 141
Code :
class Base {
...
};
class Derived : public Base {
void OnlyOwnedByDerived{
...
}
};
The question is :
1. If I used a smart pointer of the Base class to reference the Derived one, the reason why I do so is that I want to get the benefit of dynamic binding which only fits virtual functions. But if I want to to use the function that is only owned by the derived class, what should I do ?
static_cast
between the smart pointer of different class gives me an error...
Upvotes: 1
Views: 3425
Reputation: 145279
For the smart pointer itself it depends on the smart pointer. A smart pointer to Derived
is not a class derived from that kind of smart pointer to Base
.
But you can cast the raw pointer. For that you have static_cast
if you know the pointee is of derived type, and dynamic_cast
for when you don't know (or just desire the checking) and the base class is polymorphic.
Note: Ownership assumptions can be broken if the raw pointer is downcasted and then used to construct a new smart pointer. For this case the original smart pointer's ownership should be released first. Usually that's a member function called release
.
For example:
#include <iostream>
#include <memory>
struct Base
{
int x;
};
struct Derived
: Base
{
void foo() const { std::cout << x << "\n"; }
Derived( int const value ): Base{ value } {}
};
auto main()
-> int
{
using std::unique_ptr;
unique_ptr<Base> p_base{ new Derived{ 42 } };
#ifdef CHECK
unique_ptr<Derived> p_directly_converted{ p_base }; // !Nyet
#endif
unique_ptr<Derived> p_derived{
static_cast<Derived*>( p_base.release() )
};
p_derived->foo();
}
std::unique_ptr
doesn't have an associated function that performs this downcast, so it must be done manually via either static_cast
or dynamic_cast
(for a polymorphic base), plus release
.
However, std::shared_ptr
has associated functions static_pointer_cast
, dynamic_pointer_cast
and const_pointer_cast
, and other smart pointers may have ditto functions – but this depends very much on the smart pointer.
Upvotes: 0
Reputation: 21576
In C++11, there is the dynamic_pointer_cast
Which you can use:
void func(std::shared_ptr<Base> b){
b->VirtualBaseFunction();
if(auto d = dynamic_pointer_cast<Derived>(b)){
d->DerivedSpecificFunction():
....more code
}
}
Upvotes: 6
Reputation: 26040
By using std::dynamic_pointer_cast
. This will return an empty shared_ptr
if the cast is not successful.
You could potentially also use dynamic_cast
directly on the pointer managed by the smart pointer, if you don't want the ownership to be shared between the returned derived pointer:
smart_ptr_type<Base> x = ...;
auto* derived = dynamic_cast<Derived*>(x.get());
Upvotes: 3