0

I have a function that accepts a shared pointer of type Base and then std::dynamic_pointer_cast to a derived type. However, the derived pointer is a NULL and I can't see why. I have made sure to include a virtual destructor in my base class. I do not want to use a static cast as this cannot guarantee that my derived member variables and functions are preserved?

The code is as follows:

Base Class:

class Base { public: mType get_type() { return msg_type; } void set_type(mType type) { msg_type = type; } virtual ~cMsg() = default; protected: mType msg_type; message msg; }; 

Derived Class:

class Derived : public Base { public: void set_i(int j) { i = j; } int get_i() { return i; } private: int i; }; 

Function performing cast:

void callback(std::shared_ptr<Base> msg_received) { std::cout<< "Callback called\n"; auto real_msg = std::dynamic_pointer_cast<Derived>(msg_received); if (real_msg != NULL) { std::cout << "i value is: " << real_msg->get_i() << "\n"; } } 

Function creating the Derived object and calling the function:

int main() { Derived test_msg; test_msg.set_i(1); test_msg.set_type(mSystem::TEST_MSG); std::shared_ptr<Base> msg_ptr = std::make_shared<Base>(test_msg); callback(msg_ptr); return 0; } 

Any help would be appreciated.

Edit: Corrected typo

4
  • 2
    Of course. msg_ptr was constructed as a Base, not a Derived. Commented Sep 1, 2015 at 19:29
  • Also, you meant to pass msg_ptr to callback() and please clean up your example to be minimal, complete, and verifiable. Commented Sep 1, 2015 at 19:30
  • What is a "NULL type"? Commented Sep 1, 2015 at 19:35
  • NULL type is a bad naming habit of mine. I have changed it in the question. Commented Sep 1, 2015 at 19:38

2 Answers 2

6

You're totally slicing. Your dynamically allocated object (managed by that shared pointer) is just a Base, copy constructed from a Derived. You can't "get the Derived back" afterwards any more than you can design a sports car with construction plans only for one of its wheels.

I think your key confusion here is in thinking that make_shared makes something shared. It doesn't. It makes something new that will be shared.

Sign up to request clarification or add additional context in comments.

2 Comments

You are totally correct! I had completely misunderstood make_shared. I have corrected it now. I never equated make_shared/unique as being analogous to new.
@John: Mate don't worry; it's C++'s fault, not yours. This language has always been utterly stupid and it's only becoming more so by the day. I wish pages like this drove the bloomin' committee.
1

You are making shared_ptr of type Base, even if you provide it with object of type Derived. Keep in mind, all make_shared does (after allocating memory using allocator) is calling a constructor of type specified with the arguments provided to make_shared.

In your case, it creates an object of type Base, and gives it an instance of Derived. Base copy constructor is than called, passed Derived object implicitly converted to the const reference to Base.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.