在学习设计模式时我就有一个疑问,关联和继承除了用法上的区别,好像在内存上并没有什么区别,继承也是父类作为了子类的元素(内存上),关联也是这样。而且关联好像更占内存一些。这就是设计模式里问题了“依赖倒转原则”。

继承分为public继承,protect继承,private继承

public:父类中的public,protected成员到了派生类中属性不变。

protected:父类中的public,protected成员到了派生类中,都变为protected成员。

private:父类中的public,protected成员到了派生类中,都变成了private成员。

特别注意:父类中的private成员是不会被继承到子类中的(这也是关联和继承的一个区别)。

特别注意:还有一种继承被称为虚继承

详细回顾一下虚继承:

虚继承的形式:

class 派生类:virtual public 基类1,virtual public 基类2, virtual public 基类3……

{
};

构造函数过程:

首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造;

执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造;

执行成员对象的构造函数,多个成员对象的构造函数按照申明的顺序构造;

执行派生类自己的构造函数;

析构以与构造相反的顺序执行;

虚继承的实质是,在多继承中,派生类的基类中如果有过个基类继承至同一基类,那么这几个基类肯定含有这同一基类的拷贝(各自各一份),所以在派生类中如果想使用,就必须加上作用域分辨符来唯一识别。这时如果另这些基类继承时用上虚基类就可以解决这个问题了。我们可以将共同继承的基类,设为虚基类,这时从不同路径继承过来的同名的数据成员在内存中就只有一份拷贝, 同名函数也只有一个映射。

 #include<iostream>

 using namespace std;

 class Base
{
private:
int val;
public:
Base(){ cout << "Base无参构造函数" << endl; };
Base(int val){ this->val = val; cout << "Base有参构造函数" << endl; }
void print(){ cout << "val = "<<val << endl; }
}; class Sub1 :virtual public Base
{
public :
Sub1(int val) :Base(val){ cout << "Sub1含参构造函数" << endl; };
}; class Sub2 :virtual public Base
{
public:
Sub2(int val) :Base(val){ cout << "Sub2含参构造函数" << endl; }
}; class Child :public Sub1, public Sub2
{
public :
Child(int val) :Sub1(val), Sub2(val){ cout << "Child含参构造函数" << endl; }
}; int main()
{
Child child();
child.print();
}

输出结果:

Base无参构造函数
Sub1含参构造函数
Sub2含参构造函数
Child含参构造函数
val = -858993460
Press any key to continue . . .

可见Sub1,和Sub2构造函数并没有执行Base的构造函数,虚继承的构造函数是这样的,先执行虚基类的无参构造函数,然后在执行Sub1的构造函数,在执行Sub2的构造函数,在执行Child的构造函数,并且在执行Sub1和Sub2的构造函数时并不再执行Base的构造函数。

如果不用虚继承的访问方式:

 #include<iostream>

 using namespace std;

 class Base
{
private:
int val;
public:
Base(){ cout << "Base无参构造函数" << endl; };
Base(int val){ this->val = val; cout << "Base有参构造函数" << endl; }
void print(){ cout << "val = "<<val << endl; }
}; class Sub1 :public Base
{
public :
Sub1(int val) :Base(val){ cout << "Sub1含参构造函数" << endl; };
}; class Sub2 :public Base
{
public:
Sub2(int val) :Base(val){ cout << "Sub2含参构造函数" << endl; }
}; class Child :public Sub1, public Sub2
{
public :
Child(int val) :Sub1(val), Sub2(val){ cout << "Child含参构造函数" << endl; }
}; int main()
{
Child child(); //child.print() //非法的访问 child.Sub1::print();
child.Sub2::print();
}

结果:

Base有参构造函数
Sub1含参构造函数
Base有参构造函数
Sub2含参构造函数
Child含参构造函数
val = 3
val = 3
Press any key to continue . . .

C++ 虚基类 派生与继承的更多相关文章

  1. C++ (P160—)多继承 二义性 虚基类 “向上转型”

    1 多继承中,必须给每个基类指定一种派生类型,如果缺省,相应的基类则取私有派生类型,而不是和前一个基类取相同的派生类型 2 一个类的保护成员只能被本类的成员函数或者它的派生类成员函数访问 3 由于c+ ...

  2. C++ 多继承与虚基类

    转载来自:CSDN insistGoGo  (http://blog.csdn.net/insistgogo) 多继承的定义:派生类的基类大于一个 语法: class  派生类名:继承方式1 基类名1 ...

  3. C++中虚基类在派生类中的内存布局

    今天重温C++的知识,当看到虚基类这点的时候,那时候也没有太过追究,就是知道虚基类是消除了类继承之间的二义性问题而已,可是很是好奇,它是怎么消除的,内存布局是怎么分配的呢?于是就深入研究了一下,具体的 ...

  4. C++ 虚继承实现原理(虚基类表指针与虚基类表)

    虚继承和虚函数是完全无相关的两个概念. 虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝.这将存在两个问题:其一,浪费存储空间:第二,存在二义性问题,通常可 ...

  5. C++:虚基类

    4.4.3 虚基类1.没什么要引入虚基类 如果一个类有多个直接基类,而这些直接基类又有一个共同的基类,则在最底层的派生类中会保留这个间接的共同基类数据成员的多分同名成员.在访问这些同名的成员时,必须在 ...

  6. C++学习之路—继承与派生(三):多重继承与虚基类

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 多重继承是指一个派生类有两个或多个基类.例如,有 ...

  7. 【C++】继承(虚基类)

    类的继承与派生 面向对象技术强调软件的可重用性,这种重用性通过继承机制来实现.而在类的继承过程中,被重用的原有类称为基类,新创建的类称为派生类.派生类定义语法格式如下: class <派生类名& ...

  8. C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}

    C/C++:一个基类继承和多个基类继承的区别 1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性, ...

  9. C#虚基类继承与接口的区别

    类:定义新的数据类型以及这些新的数据类型进行相互操作的方法 定义方式: class Cat { } class Cat:object { } C#中所有的类都是默认由object类派生来的,显示指定或 ...

随机推荐

  1. spring-session之二:简单配置

    官方示例:https://docs.spring.io/spring-session/docs/current/reference/html5/#samples 配置Spring Session 在W ...

  2. HBuilder使用技巧

    ctrl+ Tab  切换 ctrl + shift + D 查找所写的函数

  3. phpmailer绑定邮箱

    1.配置 <?php return array ( 'email_host' => 'smtp.aliyun.com', 'email_port' => '25', 'email_u ...

  4. 解决阿里云下server 2008中tomcat不能外网访问

    1. 首先这台服务器是别人给到手的服务器, 所有环境跟我讲是全新的, 然后我开始配置tomcat; 开始安装sql 2008 r22. r1安装好之后, 本机内部怎么访问都行( . 和 127.0.0 ...

  5. 学习笔记::fft

    上次学fft还是5月份,昨天发现已经忘记怎么推导了,代码也看不懂了,就又学习了一发,大概是看menci的博客 0.fft可以进行多项式乘法,朴素的乘法跟手算一样是O(n^2),fft可以通过分治做到n ...

  6. C#获取视频文件播放长度

    下面两种方法只支持部分视频格式,一般格式mp3,wma等等支持 1.使用Shell32 添加引用,选择COM中的Microsoft Shell Controls And Automation引用 // ...

  7. Java面向对象-面向对象编程之基本概念

    面向对象这个概念,每本书上的说法定义很多. 我自己根据我的经验,自己归档总结了下, 所谓面向对象,就是 以基于对象的思维去分析和解决问题,万物皆对象: 面向对象经常和面向过程放一起讨论: 这里举例, ...

  8. Apache Shiro 权限框架

    分享一个视屏教程集合 http://www.tudou.com/home/konghao/item 1.Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码 ...

  9. 关于jquery在页面初始化时radio控件选定默认值的问题

    网上找了很多资料,都是比较旧版本的方法,新版的jquery都已经抛弃了. 正确的代码是 $('input:radio[name="statusRadios"][value=&quo ...

  10. spring mvc default-servlet mvc:resources mvc:default-servlet-handler区别

    mvc:default-servlet-handler其实就是default-servlet 交由web容器自己处理 mvc:resources spring来处理 没有被映射的url web容器来处 ...