扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
在缺省情况下,C++中的继承是按值组合的一种特殊情况,比如:
成都创新互联是专业的政和网站建设公司,政和接单;提供成都网站设计、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行政和网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!class B :virtual public A{ ... };
每个B类对象都含有其A基类子对象的所有非静态数据成员,以及在B中声明的非静态数据成员。类似地,当派生类自己也作为一个基类对象时,如:
class C :virtual public B{ ... };
则C 类对象含有在C中声明的所有非静态数据成员,以及其B子对象的所有非静态数据成员和A子对象的所有非静态数据成员。
在单继承下,这种由继承支持的.特殊形式的按值组合提供了最有效的,最紧凑的对象表示。在多继承下,当一个基类在派生层次中出现多次时就会有问题。 最主要的实际例子是
iostream 类层次结构,在下图 ostream 和 istream 类都从抽象 ios 基类派生而来,而 iostream 类又是从 ostream 和 istream 派生:
class iostream :
public istream , public ostream { ... };
缺省情况下,每个 iostream 类对象含有两个 ios 子对象:在 istream 子对象中的实例以及在 ostream 子对象中的实例。这为什么不好?从效率上而言,存储 ios 子对象的两个复本,浪费了存储区,因为 iostream 只需要一个实例。而且 ios 构造函数被调用了两次,每个子对象一次,更严重的问题是由于两个实例引起的二义性,例如:任何未限定修饰地访问 ios 的成员都将导致编译时刻错误。到底访问哪个实例?如果 ostream 和 istream 对其 ios 子对象的初始化稍稍不同,会怎样呢?怎样通过 iostream 类保证这一对 ios 值的一致性?在缺省的按值组合机制下,真的没有好办法可以保证这一点。
C++语言的解决方案是,提供另一种可替代“按引用组合”的继承机制:虚拟继承。在虚拟继承下,只有一个共享的基类子对象被继承,而无论该基类在派生层次中出现多少次。共享的基类子对象被称为虚拟基类,在虚拟继承下,基类子对象的复制及由此而引起的二义性都被消除了。
C++中虚拟继承的概念
为了解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样不仅就解决了二义性问题,也节省了内存,避免了数据不一致的问题。
class 派生类名:virtual 继承方式 基类名
virtual是关键字,声明该基类为派生类的虚基类。
在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。
声明了虚基类之后,虚基类在进一步派生过程中始终和派生类一起,维护同一个基类子对象的拷贝。
C++虚拟继承
◇概念:
C++使用虚拟继承(Virtual Inheritance),解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。
◇解决问题:
解决了二义性问题,也节省了内存,避免了数据不一致的问题。
◇二义性:
#include "stdafx.h"
#include
using namespace std;
//Base
class Base
{
public:
Base(){ cout << "Base called..." << endl; }
void print(){ cout << "Base print..." << endl; }
private:
};
//Sub
class Sub //定义一个类 Sub
{
public:
Sub(){ cout << "Sub called..." << endl; }
void print(){ cout << "Sub print..." << endl; }
private:
};
//Child
class Child : public Base, public Sub //定义一个类Child 分别继承自 Base ,Sub
{
public:
Child(){ cout << "Child called..." << endl; }
private:
};
int main(int argc, char* argv [])
{
Child c;
//不能这样使用,会产生二意性,VC下error C2385
//c.print();
//只能这样使用
c. Base::print();
c. Sub::print();
system( "pause");
return 0;
}
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流