There is a problem with the code, and as @tkausi commented, the behavior is undefined.
The problem is that you are using C-style cast which is dangerous and should be avoided in C++. From cppreference:
When the C-style cast expression is encountered, the compiler
attempts to interpret it as the following cast expressions, in this
order:
const_cast<new_type>(expression);
static_cast<new_type>(expression)
, with extensions: pointer or
reference to a derived class is additionally allowed to be cast to
pointer or reference to unambiguous base class (and vice versa) even
if the base class is inaccessible (that is, this cast ignores the
private inheritance specifier). Same applies to casting pointer to
member to pointer to member of unambiguous non-virtual base;
static_cast
(with extensions) followed by const_cast
;
reinterpret_cast<new_type>(expression);
reinterpret_cast
followed by const_cast
.
The first choice that satisfies the requirements of
the respective cast operator is selected, even if it cannot be
compiled (see example). If the cast can be interpreted in more than
one way as static_cast
followed by a const_cast
, it cannot be
compiled. In addition, C-style cast notation is allowed to cast from,
to, and between pointers to incomplete class type. If both expression
and new_type
are pointers to incomplete class types, it's unspecified
whether static_cast
or reinterpret_cast
gets selected.
Thus, in your case the compiler will select reinterpret_cast
which will just reinterpret the raw bytes of your object as something else (and it just happens that the first thing in the virtual table of p
points to method h
).
To make your program safe, you should instead use static_cast
or dynamic_cast
:
#include<iostream>
using namespace std;
class Class1 {
public:
virtual void f() {
cout << "Function f() in Class1\n";
}
};
class Class2 {
public:
virtual void h() {
cout << "Function h() in Class2\n";
}
};
int main() {
Class1 object1, *p;
Class2 object2;
p = &object1;
p = static_cast<Class1*>(&object2); // fails to compile
p->f();
return 0;
}
In this case, compilation fails as expected.
Live example: https://godbolt.org/g/noErNr
Note that if we replace static_cast
line with p = dynamic_cast<Class1*>(&object2);
the code will compile, but p
will be set to nullptr
at runtime, and trying to call p->f()
will result in an error.