Given the following code
class T {
public:
virtual ~T () {}
virtual void foo () = 0;
};
class U {
public:
U() {}
~U() {}
void bar () { std::cout << "bar" << std::endl; }
};
class A : public U, public T {
public:
void foo () { std::cout << "foo" << std::endl; }
};
int main () {
A * a = new A;
std::vector<U*> u;
std::vector<T*> t;
u.push_back(a);
t.push_back(reinterpret_cast<T*>(u[0]));
u[0]->bar ();
t[0]->foo ();
delete a;
return 0;
}
I get the output I would expect
bar
foo
However, if I change the definition of U to
class U {
public:
U() {}
virtual ~U() {}
virtual void bar () { std::cout << "bar" << std::endl; }
};
I still compile fine and without warnings/errors but the output is now
bar
bar
What is it about the virtual declaration that prevents me from calling into the foo?
Firstly, there are no virtual base classes in your example. Classes that contain virtual functions are called polymorphic. (There is such thing as “virtual base classes” in C++ but it has nothing to do with your example.)
Secondly, the behavior of your code does not depend on any virtual declarations. You have deliberately destroyed the integrity of the base pointer by using
reinterpret_cast. For this reason the behavior of the code is undefined.A direct cast from one base pointer to another (which is what you are trying to do in your code) is called cross-cast. The only cast in C++ that can carry out a cross-cast is
dynamic_cast.You can perform an indirect cross-cast without
dynamic_cast, but for that you have to downcast the pointer to the derived type first (A *) usingstatic_castand then upconvert it to another base pointer type