C++中的虚基类以及构造函数解析
来源:互联网 发布:使命召唤14知乎 编辑:程序博客网 时间:2024/06/06 01:20
当某类的部分或者全部直接基类是从另一个共同基类派生而来时,在这些直接基类中从上一级共同基类继承来的成员就拥有相同的名称。在派生类的对象中,这些同名数据成员在内存中同时拥有多个副本,同一个函数名会有多个映射。可以使用作用域分辨符来唯一标识并分别访问它们,也可以讲共同基类设置为需基类,这时从不同路径继承过来的同名函数成员在内存中就只有一份副本,同一个函数也只有一个映射。这样就解决了同名成员的唯一标识问题。
一、虚基类
先看下图:
代码:class Base0 {public:int var0;void fun();};class Base1 : public Base0 {public:int var1;};class Base2 : public Base0 {public:int var2;};class Derived : public Base2, public Base1 {public:int var;void fun();};
可知,Base1和Base2从Base0继承下来的var0和fun()在非virtual继承自Base0的情况下,var0和fun()在Derived中存在多个副本,使得Derived变得更加的臃肿。
则Derived类成员情况如图:
可以使用作用域分辨符来访问它们,如下:
Derived dr;dr.Base1::var0 = 2;dr.Base1::fun();
以下是虚基类继承方式:
代码:class Base0 {public:int var0;void fun();};class Base1 : virtual public Base0 {public:int var1;};class Base2 : virtual public Base0 {public:int var2;};class Derived : public Base2, public Base1 {public:int var;void fun();};
派生时Base0为虚基类,再以Base1、Base2作为虚基类的公有派生产生了新类Derived。这时的Derived类中,通过Base1和Base2两条路径继承下来的基类Base0中的var0和fun()只有一份副本。
则Derived类成员情况如图
二、虚继承后其派生类的构造函数
注意 : 如果虚基类声明又非默认形式的(即带参数的)构造函数,并且没有声明默认形式的构造函数,此时,在整个继承关系中,直接或者间接继承虚基类的所有派生类,都必须在构造函数的成员初始化列表中列出对虚基类的初始化。
代码:class Base0 {public: Base(int var):var0(var){}int var0;void fun();};class Base1 : public Base0 {public: Base1(int var):Base0(var){}int var1;};class Base2 : public Base0 {public: Base2(int var):Base0(var){}int var2;};class Derived : public Base2, public Base1 {public: Derived(int var):Base0(var),Base1(var),Base2(var){}int var;void fun();};
int main(){ Derived d(5); d.var = 2; d.fun(); return 0;}
建立Derived对象d时,直接调用了Base0、Base1、Base2的构造函数,但是并不会对Base0中的var0初始化三次!C++编译器对此种情况进行了处理,建立对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员由是由最远派生类(在这里是Derived类)的构造函数通过调用虚基类的构造函数进行初始化的,而该派生类的其他基类(即上例中的Base1和Base2)对虚基类构造函数的调用都自动被忽略。
- C++中的虚基类以及构造函数解析
- JS中的构造函数解析
- JS中的构造函数解析
- 继承中的构造函数解析
- C语言中的构造函数
- JS中的构造函数详细解析
- 《解析C#类中的构造函数》
- 继承中的重载以及构造函数与虚函数
- 2.c++与objective-c中的构造方法(构造函数)
- 在C#中的构造函数和解析函数
- 深入解析C++中的构造函数和析构函数
- 深入解析C++中的构造函数和析构函数
- 【C++】构造函数&析构函数的解析(应用)
- C++:实例解析构造函数、析构函数、拷贝构造函数等
- [C++]类成员冒号初始化以及构造函数内赋值
- 关于Object-c 中的构造函数与析构函数
- C++ explicit在构造函数中的作用解析
- (重要)JS中的构造函数详细解析
- eclipse中新建struts工程
- Struts2,Hibernate,Spring自定义配置文件路径
- ATL Internals 2ed复习.chapter 6.Table driven QueryInterface
- Flex中加载gif图片
- 判断一个数的所有因数的个数是偶数还是奇数
- C++中的虚基类以及构造函数解析
- C++程序设计-第七周上机实践项目
- Win7部署asp.net网站,问题逐个突破<一>---Win7 IIS 部署网站,同局域网中电脑无法访问解决方案
- Web相关Cache介绍
- 用ExternalInterface实现Flex与外部容器交互
- 火狐下firebug调试工具的使用
- Flex带进度条的多文件上传(基于Servlet)
- 将Spring与Flex整合(基于嵌入式tomcat)
- 装饰设计模式