c++基础语法:虚继承_MsSql

虚继承 的概念的提出主要是为了解决C++多继承的问题,举个最简单的例子:

复制代码 代码如下:

class animal{
        public :
              void op()
                  {cout << "hello animal" ;}
 };
class tiger : public animal {
        public :
              void tg()
                  {cout << "this is  tiger" ;}
};
class lion : public animal {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
class liger : public tiger, public lion {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
int main()
{
     class liger  oneliger ;
     liger.op() ; 
}

上面的 liger.op() ;会报错,会提示模糊的成员变量,因为tiger和lion中都包含父类animal的op()操作。
此时内存中的oneliger对象布局从低到高是下面这样的:
1、animal的成员变量

2、继承tiger的成员变量
      //包括 op()

3、继承lion的成员变量
     / /也包括op()

4、liger本身的成员变量

PS: 对象在内存中的布局首先是如果有虚函数的话就是虚表,虚表就是指向一个函数指针数组的指针,然后就是成员变量,如果是普通继承则首先是最根父类的成员变量,然后是次父类成员变量,依次而来最后是本身的成员变量[虚继承相反],成员函数被编译成全局函数不存储在对象空间内,需要调用成员函数的时候,通过类名找到相应的函数,然后将对象的this指针传给函数:

比如这样的代码 
CTest     test; 
test.print(); 

编译器在内部将转换为:(伪代码) 
CTest   test; 
CTest_print(   &test   );   //   CTest的print函数转换为:CTest_print(   CTest*   const   this); 

所以这就和普通函数调用差别不大了
实际应该是函数找到对象,即根据this指针

为了解决 上面多继承的问题,所以c++中提出了虚继承的概念,虚继承就是在子类中只保留一份父类的拷贝,拿上面的类子来说,就是“如果有一份父类的拷贝的话就用父类的拷贝,如果没有就加入一份拷贝” :

复制代码 代码如下:

class animal{
        public :
              void op()
                  {cout << "hello animal" ;}
 };
class tiger : public virtual animal {
        public :
              void tg()
                  {cout << "this is  tiger" ;}
};
class lion : public virtual animal {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
class liger : public tiger, public lion {
        public :
              void lo()
                  {cout << "this is lion" ;}
};
int main()
{
     class liger  oneliger ;
     liger.op() ; 
}

此时liger对象在内存中的布局就变成了:
4、animal的成员变量

3、继承tiger的成员变量
      //包括 op()

2、继承lion的成员变量
     //已经包含一份拷贝,所以 已经不包括op()

1、liger本身的成员变量

这样内存中就只有一份animal对象的拷贝,所以就不会存在模糊的问题;

时间: 2024-10-29 03:31:43

c++基础语法:虚继承_MsSql的相关文章

c++基础语法:虚继承

虚继承 的概念的提出主要是为了解决C++多继承的问题,举个最简单的例子:复制代码 代码如下:class animal{        public :              void op()                  {cout << "hello animal" ;} };class tiger : public animal {        public :              void tg()                  {cout &l

c++基础语法:普通继承_C 语言

1.首先说一下类的成员函数或者成员变量的3个属性:public:    对于对象和成员函数都是可见的,即可以引用protected: 对于成员函数是可见的,但对于对象来说是不可见的,这个声明主要是用在继承 中,下面将讨论private:   对于成员函数是可见的,对于对象是不可见的 2.然后看一下继承方式: 基类成员关键字            派生类继承方式        派生类对基类成员访问权限public                    public                相

jsp基础语法 二 注释的使用

我的一个同学问我,java中有"//"这个样的注释,用起来挺方便的,jsp的注释难道不是这个吗?用"//"在jsp中不行. 对于学习了这么长时间的jsp,注释是最基本的.jsp中的注释不同于java. 在jsp中支持两种注释,一种是显示注释,这种注释客户端是允许看见的,另外一种注释是隐式注释,此种注释客户端是无法看见的. 显示注释语法: <!--注释内容--> 隐式注释语法: 格式一:// 注释,单行注释: 格式二:  /* 注释 */,多行注释: 格式

JAVA 入坑教程 | 基础语法

Java 基础语法  一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.下面简要介绍下类.对象.方法和实例变量的概念. 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有:摇尾巴.叫.吃等. 类:类是一个模板,它描述一类对象的行为和状态. 方法:方法就是行为,一个类可以有很多方法.逻辑运算.数据修改以及所有动作都是在方法中完成的. 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定. 第一个J

Swift与C#的基础语法比较

背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对比来加深认识. 所以做了一个简单的比较列表. 下面是基础语法的比较:     Swift C#(4.0以上) 常量定义: let name="cyq.data" Const name="cyq.data"; 变量定义: 指定类型: var name="cyq.

温习Javascript基础语法之词法结构_javascript技巧

前面的话 javascript是一门简单的语言,也是一门复杂的语言.说它简单,是因为学会使用它只需片刻功夫:而说它复杂,是因为要真正掌握它则需要数年时间.实际上,前端工程师很大程度上就是指javascript工程师.前端入门容易精通难,说的是前端,更指的是javascript.本文是javascript基础语法的第一篇--词法结构 与java关系 关于javascript有这样一个说法,java和javascript的关系是雷锋和雷锋塔的关系.那到底有没有关系呢 javascript最开始的名字

最近几天把马士兵的 基础语法,面向对象视频看完, 感觉晕呼呼的

问题描述 哎呀小弟不才呀刚接触java最近几天把马士兵的基础语法,面向对象视频看完,感觉晕呼呼的大家帮找找方向 解决方案 解决方案二:这个是很基础的问题,如果这关过不了,以后的东西都不能进行,怎么谈方向啊,只有把基础学扎实了,后面才会好学,到时候,你再问这个问题也不迟啊?解决方案三:这个道理我也了解所以现在找基础呀,主要有没有学习的方法借鉴一下解决方案四:呵我正在看解决方案五:再看一遍就过吧,自己编几个小代码,自己写代码要比看教程印象深.加油,和你一起奋斗在java的战线上!解决方案六:引用2楼

【Java】基础语法

虽然说Java又是一门新的编程语言,但基础的语法部分还都是可以和之前学习的编程语言一样的. 既然被称之为语法,那就必然有一定的规则.其中,在标识符和关键字部分,我们就可以很明显的看出一些强制性的要求. 关键字不能作为标识符,标识符为小写字母等,这有着一系列的规则,然而我们也并不需要去记,按着常规走,结合自身的以往的一些经验,就没什么问题. 学习了这么久的编程语言,也是总结过很多次关于数据的知识点.而这一次,一层一层,把它们之间的关系联系的更紧密了. 数据在程序中是少不了的.而我们如何获取数据或者

C++对象布局及多态探索之菱形结构虚继承

这次我们看看菱形结构的虚继承.虚继承的引入本就是为了解决复杂结构的继承体系问题.上一篇我们在讨论虚继承时用的是一个简单的继承结构,只是为了打个铺垫. 我们先看看这几个类,这是一个典型的菱形继承结构.C100和C101通过虚继承共享同一个父类C041.C110则从C100和C101多重继承而来. struct C041{ C041() : c_(0x01) {} virtual void foo() { c_ = 0x02; } char c_;};struct C100 : public vir