I am having trouble understanding casting of shared_ptr
.
This thread does a pretty good job explaining the behavior with normal pointers, and the result is very intuitive - exactly what I would expect. However, shared_ptr
show different results - I created 3 classes, one base and two derived and played around a bit with using ***_ptr_cast
:
#include <iostream>
#include <memory>
using namespace std;
struct Base
{
virtual void f() { cout << "Base" << endl; }
string name = "Base";
};
struct FirstDerived : public Base
{
void f() override { cout << "FirstDerived" << endl; }
void firstDerived() { cout << "FirstDerived only method" << endl; }
string name = "FirstDerived";
};
struct SecondDerived : public Base
{
void f() override { cout << "SecondDerived" << endl; }
void secondDerived() { cout << "SecondDerived only method" << endl; }
string name = "SecondDerived";
};
int main()
{
FirstDerived fd;
std::shared_ptr<Base> bf = make_shared<Base>(fd);
std::shared_ptr<FirstDerived> fdp = std::static_pointer_cast<FirstDerived>(bf);
if (fdp)
{
fdp.get()->f();
fdp.get()->firstDerived();
//cout << fdp.get()->name;
}
FirstDerived sd;
std::shared_ptr<Base> bs = make_shared<Base>(sd);
std::shared_ptr<SecondDerived> sdp = std::static_pointer_cast<SecondDerived>(bs);
if (sdp)
{
sdp.get()->f();
sdp.get()->secondDerived();
//cout << sdp.get()->name;
}
return 0;
}
The output for this program shows (funnily cout << fdp.get()->name;
is not possible because it will segfault):
Base
FirstDerived only method
Base
SecondDerived only method
Researching a bit further, I came to the conclusion that static_cast
might be the wrong cast, so I changed it to a dynamic_cast
. The dynamic version however will never return a valid value, even if I am casting to the correct derived version.
The desired result would be, that only if the initial object was of the type of the one that is being cast to in the next step then there will be a result. Else it should be null.
How should I correctly do this, is there a cast-version for what I am searching?