views:

42

answers:

2

I'm using boost::shared_ptr's and boost::dynamic_pointer_cast. I have a base class, an interface that inherits from that base class, and then a class that inherits from that one.

So A -> B -> C. I create an object of type C and it's stored as a shared_ptr of type A. Then I try and do a dynamic_pointer_cast to type B, but boost::dynamic_pointer_cast returns NULL.

When I do a boost::static_pointer_cast and use the pointer, it doesn't crash the program. But I would prefer if the dynamic cast worked.

Why is this happening?

EDIT: Here's a compact section of the code (otherwise it's too long to put here). Tell me if you need more than the header files.

class A
{
public:
    virtual ~A();

    /** Contains other virtual functions and some static functions */

protected:
    A();
};

class B
{
public:
    /** Pure virtual functions */

    /** Note: No destructor is declared (when I next have
        access to the computer I'll try adding a virtual destructor) */

protected:
    B();
};

class C
{
public:
    C();

    virtual ~C();

    /** Implementation of pure virtual functions */
};

Also, the dynamic_pointer_cast for this same code works on another computer with the exact same classes. Which has me at a complete loss. The code also worked until about a week ago when I made a change. When I reverted the change, the problem still occurred.

+1  A: 

Some code would help. The obvious first guess is that perhaps you forgot to give A a virtual destructor.

Ross Smith
It doesn't *need* a virtual destructor (highly recommended though!) so much as it needs *a* virtual function.
GMan
A: 

It's hard to say without your definitions of A, B, and C, along with your usage.

Compare your program to the following:

#include <boost/shared_ptr.hpp>
#include <iostream>

struct A { virtual ~A() {} };
struct B : A {};
struct C : B {};

int main()
{
    boost::shared_ptr<A> x(new C);
    boost::shared_ptr<B> y(boost::dynamic_pointer_cast<B>(x));

    std::cout << std::boolalpha
                << (y.get() != 0) << std::endl;
}
GMan