I have a diamond inheritance structure in my code in which I have a pointer to the bottom object. I tried to case this to a pointer to the left of the two diamond sides, cast it again to the top of the diamond, and again to the right side. But apparently, C++ kind of remembers the order of casting and things don't work as expected. Example code:
#include <iostream>
class A
{
};
class B1 : public A
{
public:
virtual int Return1() = 0;
};
class B2 : public A
{
public:
virtual int Return2() = 0;
};
class C : public B1, public B2
{
public:
virtual int Return1() { return 1; }
virtual int Return2() { return 2; }
};
int main()
{
C c;
B1* b1 = &c;
A* a = b1;
B2* b2 = (B2*)a;
std::cout << "Return2() = " << b2->Return2();
}
This results in Return2() = 1
, so apparently this approach is wrong. I know that something like this works in C#, so my question would be: Is there a way in C++ to do what I'm attempting here or - if not - why is this not an option?
A A
| |
B1 B2
\ /
C
not a diamond (1 A).
Avoid C-cast which might result in reinterpret_cast
, and most reinterpret_cast
usage leads to Undefined Behavior (UB).
You might use dynamic_cast
in your case to have expected behavior (A
need to be polymorphic for that, default virtual destructor does the job):
class A
{
public:
virtual ~A() = default; // Added to allow dynamic_cast
};
class B1 : public A
{
public:
virtual int Return1() = 0;
};
class B2 : public A
{
public:
virtual int Return2() = 0;
};
class C : public B1, public B2
{
public:
// override used for extra check from compiler.
int Return1() override { return 1; }
int Return2() override { return 2; }
};
int main()
{
C c;
B1* b1 = &c;
A* a = b1;
B2* b2 = dynamic_cast<B2*>(a); // C-cast replaced by dynamic_cast
assert(b2 != nullptr);
std::cout << "Return2() = " << b2->Return2();
}