Is it possible to dynamic_cast from one base class to another?
For instance I have code like that
class Base1
{
virtual void wonderFULL() = 0;
};
class Base2
{
// all this weird members
};
class Derived : public Base1, public Base2
{
// not so weird members
};
int main()
{
Derived Wonder;
magicFunction(&Wonder);
return 0;
}
void magicFunction开发者_开发百科(Base2 *ptr)
{
if (Base1 *b1 = dynamic_cast<Base1 *>(ptr))
b1->wonderFULL();
}
However wonderFULL is never executed due to impossibility to cast ptr to b1. Is it possible at all to perform such a conversion?
This
#include <iostream>
class Base1 {
public:
virtual void wonderFULL() = 0;
};
class Base2 {
public:
virtual ~Base2() {} // added so the code compiles
};
class Derived : public Base1, public Base2 {
virtual void wonderFULL() {std::cout << "wonderful\n";} // added so the code compiles
};
void magicFunction(Base2 *ptr) {
if (Base1 *b1 = dynamic_cast<Base1 *>(ptr))
b1->wonderFULL();
}
int main() {
Derived Wonder;
magicFunction(&Wonder);
return 0;
}
prints wonderful
for me. My conclusion is that you're not showing the code necessary for your problem to reproduce.
Take (a copy of) your actual code and by removing uneccessary code step by step distill it until you derive at a self-contained (needs no other headers except from the std lib), compilable example that reproduces the problem. Very likely you will find the problem while doing so. However, if you don't, you have the perfect repro case to come back here and ask about.
You have some syntax errors, but your real problem is dynamic_cast
won't work properly if your base classes don't have at least one virtual function.
If you make it look like:
class Base2
{
public:
virtual ~Base2() {}
// all this weird members
};
And then fix your other errors:
wonderFULL
is private, and never defined.
magicFunction
is declared after it is used.
Then everything works.
You can cast up the hierarchy then back down:
void magicFunction(Base2& ptr)
{
try
{
Derived& d = dynamic_cast<Derived&>(ptr);
Base1& b = dynamic_cast<Base1&>(d);
b.wonderFULL();
}
catch(const std::bad_cast&)
{ /* Cast failed */ }
}
Going by what I understand of the way some C++ compilers arrange the class hierarchy in memory it should be possible to cast from one base class to another, but you have to first cast to the derived class.
Therefore you would need to do something like:
Base1* b1 = dynamic_cast<Derived*>(ptr);
This casts the given pointer ptr
to the derived class, and then it gets implicitly cast to its other base class pointer.
However another easier way to do this would be to just have a method in the Base2 class that returns a Base1 pointer, and the derived class can implement this itself without any tricky code. (The same function in Base2 can just return NULL if you don't want a pure virtual class).
I've found the problem. It was not about dynamic_casts. I was checking wrong object which was not inherited from abstract base. Thanks.
精彩评论