一、主要目的
1、掌握虚基类各直接派生类的构造函数和间接派生类的构造函数的基本语法;
2、理解最派生类的概念、对象存储结构;
3、理解虚基类表指针并简单应用;
4、最派生类对象中虚基类表指针的应用。
二、运行原理
1. 设计了四个类:A、B、C和D。其中,A是基类,B和C是A的虚基类,D是从B和C派生出来的。
2. 在main函数中,创建了一个D类的对象obj,并将其地址转换为int指针p。
3. 使用该指针p,以非常特殊的方式访问和输出了部分数据成员的值。
三、代码实现
#include <iostream>
using namespace std;
class A{
public:
A(int aa) : a(aa) {}
protected:
int a;
};
class B :virtual public A {
public:
B(int aa = 1, int bb = 2) : A(aa), b(bb){}
protected:
int b;
};
class C :virtual public A {
public:
C(int aa = 1, int cc = 2) : A(aa), c(cc) {}
protected:
int c;
};
class D :public B, public C {
public:
D(int aa = 1, int bb = 2, int cc = 3, int dd = 4) : A(aa), B(aa,bb), C(aa, cc),d(dd) {}
private:
int d;
};
int main()
{
D obj;
/*cout << sizeof(D) << endl;
cout << sizeof(C) << endl;
cout << sizeof(B) << endl;
cout << sizeof(A) << endl;*/
int *p;
p = (int*) &obj;
cout << *((int*)*(p+0)+1) << endl;
cout << *(p+1)<< endl;
cout << *((int*)*(p + 2)+1) << endl;
cout << *(p + 3) << endl;
cout << *(p + 4) << endl;
cout << *(p + 5) << endl;
return 0;
四、结果展现
五、总结
1. 在虚继承中,虚基类的部分会在派生类的末尾,而且只会存在一份。
2. 注意,这里的代码是跳过了C++的类型系统,直接进行内存操作,这是非常危险的行为。因为在访问内存时,如果没有完全理解对象内存布局,那么可能会访问到错误的内存位置,导致程序崩溃或者数据错误。
3. 在实际编程中,应尽量避免直接操作内存,而是应该通过类提供的公有接口来进行操作,以保证数据的安全性和程序的稳定性。
4. 在C++中,虚继承的内存布局可能因编译器的实现而改变,因此对虚继承的内存布局有深入理解的人才能尝试这样的操作。