Question

I have the following hierarchy of classes

A
|-B   I
  |-C-|

A is class of the system; B and C are my own.

In the system there is also a function that returns a pointer to the instance of A.

I is a minimal class, that if possible doesn't even any members.

When I do

A* pA= A::GetInstance();
if(!pA)
    return;

I* pI= dynamic_cast<I*>(pA);
if(!pI)
    return;

and my Instance is a C, the dynamic_cast always fails! And if I do Watch to the pA variable and open the respective node, it displays a line with the I class, making me think it is castable! Strange! ...

So, after reading some info in the Internet, it seems the class I supposedly needs to have something virtual.

Things I tried:

  • Change the cast to be a static_cast. It doesn't even compile! I turned back to the dynamic_cast!

  • Add a virtual destructor to it with an empty body. dynamic_cast fails!

  • Change that destructor to be a pure virtual. This doesn't even compile (Note: B and C class already had virtual destructors!)

  • Removed that destructor and implemented a void Dumb() method with an empty body in the I class. The dynamic_cast fails again!

  • Changed that method to be a pure virtual and in C add that void Dumb() method with an empty body. It is failing one more time!

Please, what can I do to know whether my pA "is an" I?

UPDATE: by popular request, I added some minimal code for the classes:

// class A is not mine, and it indirectly inherits
// public CObject and has a virtual destructor!

class B: public A
{
public:
  virtual ~B();

 // the code!
};

class I
{
};

class C: public B, I
{
public:
  virtual ~B();

 // the code!
};
Was it helpful?

Solution 2

The following works:

#include <cstdio>

class A { public: virtual ~A() { } };
class B : public A { };
class I { };
class C : public B, public I { };

int main()
{
    C c;
    A* a = &c;
    if (dynamic_cast<I*>(a))
        std::printf("it's a C\n");
    else
        std::printf("it's not a C\n");
    return 0;
}

Note the second public in C's declaration.

OTHER TIPS

class C: public B, I
{ //...

I is a private base class of C, since you didn't specify the access of I. (Your public applies only to B.) Therefore an object of type C is not in fact an I. dynamic_cast can only follow public inheritance relationships.

You may get different results if you change that to:

class C: public B, public I
{ //...

First cast it to C, then you know it is an I:

A* pA= A::GetInstance();
if(!pA)
    return;

if( C* pC = dynamic_cast<C*>(pA) ) {
    I* pI= dynamic_cast<I*>(pC);
    if(!pI) return; // unnecessary, but you can keep it
    .
    .
    .
    /// do your thing with pI here
    .
    .
    .
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top