菱形继承
来源:互联网 发布:蓝博清单计价软件 编辑:程序博客网 时间:2024/04/29 05:52
//菱形继承
菱形继承也是多继承的一种方式。
看一段代码:
class A
{
public:
virtual void func1()
{
cout<<"A::func1"<<endl;
}
virtual void func2()
{
cout<<"A::func2"<<endl;
}
public:
int _a;
};
class B :public A
{
public:
virtual void func1()
{
cout<<"B::func1"<<endl;
}
virtual void func3()
{
cout<<"B::func3"<<endl;
}
public:
int _b;
};
class C :public A
{
public:
virtual void func1()
{
cout<<"C::func1"<<endl;
}
virtual void func4()
{
cout<<"C::func4"<<endl;
}
public:
int _c;
};
class D :public B,public C
{
public:
virtual void func1()
{
cout<<"D::func1"<<endl;
}
virtual void func5()
{
cout<<"D::func5"<<endl;
}
public:
int _d;
};
void Test()
{
D d;
d._a = 10;
}
int main()
{
Test();
return 0;
}
这个时候会形成一个菱形继承:如图所示:
而在这时编译会报出错误:
他说:对_a的访问不正确。
打开调试的监视窗口:
在监视窗口中我们可以看到因为B继承了A,所以在B中有一个_a,而C也继承了A,C中也有一个_a,而D继承了B,C,所以在d中也会有两个_a的出现,所以在你访问_a的时候会被报出对_a的不明确的错误。
所以在菱形继承中会出现二义性和数据冗余。
为了解决菱形继承中的二义性和数据冗余,在继承关系中引入了虚继承。在class B :public A,前面加上virtual关键字 即(class B:virtua public A),
同时在class C :public A,前面加上virtual关键字 即(class C:virtua public A),
代码变为:class A
{
public:
virtual void func1()
{
cout<<"A::func1"<<endl;
}
virtual void func2()
{
cout<<"A::func2"<<endl;
}
public:
int _a;
};
class B :virtual public A
{
public:
virtual void func1()
{
cout<<"B::func1"<<endl;
}
virtual void func3()
{
cout<<"B::func3"<<endl;
}
public:
int _b;
};
class C :virtual public A
{
public:
virtual void func1()
{
cout<<"C::func1"<<endl;
}
virtual void func4()
{
cout<<"C::func4"<<endl;
}
public:
int _c;
};
class D :public B,public C
{
public:
virtual void func1()
{
cout<<"D::func1"<<endl;
}
virtual void func5()
{
cout<<"D::func5"<<endl;
}
public:
int _d;
};
void Test()
{
D d;
d._a = 10;
}
int main()
{
Test();
return 0;
}
这个时候就不会报出错误。
调试打开监视窗口:
这个时候对象d中_a的改变也会改变B中的_a和C中的_a.
也就是说编译器把_a放在了一个地方。
这时打开调试内存窗口:
这个时候会发现_a存在_d的后面。
所以在菱形继承中是先继承的放在前面。
这时我们会发现0x00000002上面还有一个地址,再打开一个内存窗口观察:
我们会发现这个地址存的是虚基表的地址,而虚基表中存的是偏移量(即到_a的偏移量)。
而虚基表的地址上面还有一个地址,这个地址其实是虚表的位置。
而虚表的位置存着虚函数的地址,通过地址可以找到对应的虚函数。
总结:虚继承是通过多开空间来存放虚表和虚基表的地址,而通过虚基表中的偏移量可以找到他们所共有的成员变量。通过虚表来找到对应的虚函数。
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- 菱形继承
- mybatis关系映射之一对多和多对一
- Tomcat上进行项目部署与WAR包含义
- JMS学习一(JMS介绍)
- VBA中的数据字典,可以理解为Java中的Map
- 格林威治时间
- 菱形继承
- 欢迎使用CSDN-markdown编辑器
- hadoop 2.8.1 windows7 搭建过程
- Leetcode 395. Longest Substring with At Least K Repeating Characters
- 线程池
- 【poj2387】Til the Cows Come Home 【USACO 2004 November】
- linux常用命令二
- 【NOIP2012提高组】同余方程 (扩展欧几里得算法)
- hdu 1325 Is It A Tree? (并查集)