I have come up with some confusing situations. Below are they.
#include <iostream>
using namespace std;
class Base {
public:
Base(int num) : data(num) {
cout << "BASE : " << num << endl;
}
virtual ~Base() = default;
virtual void func1() {
cout << "Base func1 called : " << data << endl;
}
virtual void func3() {
cout << "Base func3 called : " << data << endl;
}
private:
int data;
};
class Interface {
public:
Interface() {
cout << "INTERFACE : " << endl;
}
virtual ~Interface() = default;
virtual void func2() {
cout << "Interface func2 called" << endl;
}
};
class Derived : public Interface, public Base {
public:
Derived() : Base(0) {
cout << "DERIVED : hh" << endl;
}
virtual ~Derived() = default;
virtual void func1() override {
cout << "Derived fuc1 called" << endl;
}
virtual void func3() override {
cout << "Derived fuc3 called" << endl;
}
virtual void func2() override {
cout << "Derived fuc2 called" << endl;
}
};
int main() {
//Interface* a = new Derived(); // derived func2 called
//Base* a = new Derived(); // derived func1 called
//Derived* a = new Derived(); // derived func2 called
void* a = new Derived(); // derived func1 called
auto b = (Interface*)a;
b->func2();
...
}
When executing b->func2()
, the result is different by the explicit type of variable a.
The results are in the comments.
Why are they different when executing b->func2()
?
This is undefined behavior. The usual semantics of converting a pointer to a derived class to a pointer to its base class apply only, well, when you convert a pointer to a derived class into a pointer to its base class. But that's not what happens here.
An intermediate conversion into some other pointer, like a
void *
voids all warranty (pun not intended).