How to implement polymorphism using std :: shared_ptr?

I saw some other questions on this topic, but still have not found an answer - in my opinion, I missed something:

I defined two simple test classes:

class TestBase { public: TestBase ( ) { }; ~ TestBase ( ) { }; protected: inline virtual int getInt ( ) { return 0; } }; class TestDerived : public TestBase { protected: inline int getInt ( ) override { return 1; } }; 

I declared typedefs to simplify their use with std::shared_ptr:

 typedef std::shared_ptr<TestBase> spBase; typedef std::shared_ptr<TestDerived> spDerived; 

Problem: I cannot compile code to use these shared_ptr declarations polymorphically, although base in all of these cases is actually an instance of spDerived :

 spBase base; spDerived derived = static_cast < spDerived > ( base ); 

error: there is no corresponding function to call in 'std :: shared_ptr :: shared_ptr (spBase &)

 spDerived derived = dynamic_cast < spDerived > ( base ); 

error: cannot dynamic_cast base '(of type' spBase {aka class std :: shared_ptr}) for input 'spDerived {aka class std :: shared_ptr} (target is not a pointer or link)

 spDerived derived = static_pointer_cast < spDerived > ( base ); 

error: conversion from 'std :: shared_ptr> to non-scalar type' SpDerived {aka std :: shared_ptr} requested

 spDerived derived = dynamic_pointer_cast < spDerived > ( base ); 

error: conversion from 'std :: shared_ptr> to non-scalar type' SpDerived {aka std :: shared_ptr} requested

I use C ++ 11 in an Ubuntu 14.04 box with the standard GCC toolchain. The compiler is gcc-4.9. What am I doing wrong? Is it possible to use the shared_pointer parameter polymorphically?

+8
gcc polymorphism casting c ++ 11 shared-ptr
source share
1 answer

The type passed to std::static_pointer_cast and std::dynamic_pointer_cast , because the template argument of the first type is the type of the converted pointer type itself, not the smart pointer type:

 static_pointer_cast<T>(arg); .~~~^ v template <class T, class U> .~~~~^ v shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r); dynamic_pointer_cast<T>(arg); .~~~~^ v template <class T, class U> .~~~~^ v shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r); 

With that said, you can call it as shown below:

 spBase base = std::make_shared<TestDerived>(); spDerived derived = std::dynamic_pointer_cast<spDerived::element_type>(base); // or: spDerived derived2 = std::dynamic_pointer_cast<TestDerived>(base); 
+13
source share

All Articles