多继承时,父类们函数里的this指向的地址是不一样的。
看以下例子:
#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;
}
打印结果得到:
A类函数里的this和C类函数里的this指向同一个地址,而B类函数里的this指向了往后偏移4个字节的地址。
关于多继承的储存结构可以参考这篇文章:从汇编的角度了解C++原理——类的储存结构和函数调用
存在的问题
当在父类函数里调用子类函数时可能会崩溃。如以下例程:
#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;
}
运行后会崩溃,因为exec中的(this->*func)();,this指向的并不是C类里的this,所以会访问到野指针,导致程序崩溃。
这里应该对exec做一个修改:
void exec(void *realSelf) {
if (func != NULL) ((B*)realSelf->*func)();
}
使用时把C对象的首地址传进去。