Consider the following code:
struct Base {};
struct Derived : public virtual Base {};
void f()
{
Base* b = new Derived;
Derived* d = static_cast<
Consider the following function foo:
#include
struct A
{
int Ax;
};
struct B : virtual A
{
int Bx;
};
struct C : B, virtual A
{
int Cx;
};
void foo( const B& b )
{
const B* pb = &b;
const A* pa = &b;
std::cout << (void*)pb << ", " << (void*)pa << "\n";
const char* ca = reinterpret_cast(pa);
const char* cb = reinterpret_cast(pb);
std::cout << "diff " << (cb-ca) << "\n";
}
int main(int argc, const char *argv[])
{
C c;
foo(c);
B b;
foo(b);
}
Although not really portable, this function shows us the "offset" of A and B. Since the compiler can be quite liberal in placing the A subobject in case of inheritance (also remember that the most derived object calls the virtual base ctor!), the actual placement depends on the "real" type of the object. But since foo only gets a ref to B, any static_cast (which works at compile time by at most applying some offset) is bound to fail.
ideone.com (http://ideone.com/2qzQu) outputs for this:
0xbfa64ab4, 0xbfa64ac0
diff -12
0xbfa64ac4, 0xbfa64acc
diff -8