In the case of multiple inheritance, the addresses pointed to by this in the functions of the parent classes are different.
Look at the following example:
#include <iostream>
using namespace std;
class A {
public:
void printA() {
cout << this << endl; }
int a;
};
class B {
public:
void printB() {
cout << this << endl; }
int b;
};
class C : public A, public B {
public:
C() {
}
void print() {
printA();
printB();
cout << this << endl;
}
int c;
};
int main()
{
C *c = new C;
c->print();
return 0;
}
The printing result is:
this in class A function and this in class C function point to the same address, while this in class B function points to an address offset by 4 bytes.
For information on the storage structure of multiple inheritance, please refer to this article: Understanding C++ principles from an assembly perspective - class storage structures and function calls
Problems
It may crash when calling a subclass function from within a parent class function. Such as the following routine:
#include <iostream>
using namespace std;
class Base {
};
class A : public Base {
int a;
};
class B {
public:
void exec() {
if (func != NULL)
(this->*func)();
}
int b;
void (B::*func)() {
NULL };
};
class C : public A, public B {
public:
C() {
func = static_cast<void (B::*)()>(&C::print);
}
void print() {
if (data != NULL) cout << *data << endl;
}
int *data {
NULL };
};
int main() {
int data = 10;
C *c = new C;
c->data = &data;
c->exec(c);
return 0;
}
It will crash after running because (this->*func)(); in exec, this does not point to this in class C, so a wild pointer will be accessed, causing the program to crash.
A modification should be made to exec here:
void exec(void *realSelf) {
if (func != NULL) ((B*)realSelf->*func)();
}
When using, pass in the first address of the C object.