C++入门经典-例8.8-虚继承
1:以前讲到从CBird类和CFish类派生子类CWaterBird时,在CWaterBird类中将存在两个CAnimal类的复制。那么如何在派生CWaterBird类时使其只存在一个CAnimal基类呢?C++语言提供的虚继承机制能够解决这个问题。
代码如下:
// 8.8.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> using namespace std; class CAnimal //定义一个动物类 { public: CAnimal() //定义构造函数 {cout << "动物类被构造"<< endl; //输出信息 }void Move() //定义成员函数 {cout << "动物能够移动"<< endl; //输出信息 } }; class CBird : virtual public CAnimal //从CAnimal类虚继承CBird类 { public:CBird() //定义构造函数 {cout << "鸟类被构造"<< endl; //输出信息 } void FlyInSky() //定义成员函数 {cout << "鸟能够在天空飞翔"<< endl; //输出信息 }void Breath() //定义成员函数 {cout << "鸟能够呼吸"<< endl; //输出信息 } }; class CFish: virtual public CAnimal //从CAnimal类虚继承CFish { public:CFish() //定义构造函数 {cout << "鱼类被构造"<< endl; //输出信息 }void SwimInWater() //定义成员函数 {cout << "鱼能够在水里游"<< endl; //输出信息 }void Breath() //定义成员函数 {cout << "鱼能够呼吸"<< endl; //输出信息 } }; class CWaterBird: public CBird, public CFish //从CBird和CFish类派生子类CWaterBird { public:CWaterBird() //定义构造函数 {cout << "水鸟类被构造"<< endl; //输出信息 } void Action() //定义成员函数 {cout << "水鸟既能飞又能游"<< endl; //输出信息 } }; int main(int argc, char* argv[]) //主函数 {CWaterBird waterbird; //定义水鸟对象return 0; }
View Code
运行结果:
上述代码中,在定义CBird类和CFish类时使用了关键字virtual,CFish类从基类CAnimal派生而来。实际上,虚继承对CBird类和CFish类没有多少影响,却对CWaterBird类产生了很大的影响。CWaterBird类中不再有两个CAnimal类的复制,而只存在一个CAnimal的复制。
通常,在定义一个对象时,先依次调用基类的构造函数,最后才调用自身的构造函数。但是对于虚继承来说情况有些不同。在定义CWaterBird类的对象时,先调用基类CAnimal的构造函数,然后调用CBird类的构造函数,这里CBird类虽然为CAnimal的子类,但是在调用CBird类的构造函数时将不再调用CAnimal类的构造函数。对于CFish也是同样的道理。
转载于:https://www.cnblogs.com/lovemi93/p/7573830.html
C++入门经典-例8.8-虚继承相关推荐
- C++入门经典-例8.1-类的继承
1:继承是面向对象的主要特征(此外还有封装和多态)之一,它使得一个类可以从现有类中派生,而不必重新定义一个新类.继承的实质就是用已有的数据类型创建新的数据类型,并保留已有数据类型的特点,以旧类为基础创 ...
- C++入门经典-例6.23-字符串数组赋值与string
C++入门经典-例6.23-字符串数组赋值与string 1:代码如下: // 6.23.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #i ...
- C++入门经典-例2.14-使用移位运算
C++入门经典-例2.14-使用移位运算 1:代码如下: // 2.14.cpp : 定义控制台应用程序的入口点. //#include "stdafx.h" #include & ...
- Java小白入门200例80之Java继承(extends)
作者简介 作者名:编程界明世隐 简介:CSDN博客专家,从事软件开发多年,精通Java.JavaScript,博主也是从零开始一步步把学习成长.深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢 ...
- Visual C++ 2008入门经典 第九章类的继承和虚函数
// 第九章类的继承和虚函数 //.cpp: 主项目文件. //1 继承如何与面向对像的编程思想适应 //2 根据现有类定义新类 //3 使用protected关键字为类成员指定新的访问特性 //4 ...
- Visual C++ 2008入门经典 第九章类的继承和虚函数(二)
//9.6.7 虚析构函数 /*#include "stdafx.h" #include <iostream> using namespace std; using n ...
- C++入门经典-例6.14-通过指针连接两个字符数组
1:字符数组是一个一维数组,引用字符数组的指针为字符指针,字符指针就是指向字符型内存空间的指针变量. char *p; char *string="www.mingri.book" ...
- C++入门经典-例4.7-变量的作用域
1:代码如下: // 4.7.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...
- C++入门经典-例9.4-默认模板参数
1:默认模板参数就是在类模板定义时设置类型形式参数表中的一个类型参数的默认值,该默认值是一个数据类型.有了默认的数据类型参数后,在定义模板的新类型时就可以不进行指定.代码如下: // 9.4.cpp ...
- C++入门经典-例8.3-子类显示调用父类构造函数
1:当父类含有带参数的构造函数时,创建子类的时候会调用它吗?答案是通过显示方式才可以调用. 无论创建子类对象时调用的是那种子类构造函数,都会自动调用父类默认构造函数.若想使用父类带参数的构造函数,则需 ...
最新文章
- 淘宝技术架构从1.0到4.0的演变
- 初学ACM之路(训练大纲)
- 使用反射建立一个用于生产短信对象的工厂方法
- call 在mysql,在MYSQL上选择CASE和CALL程序
- webpack(三)使用 babel-loader 转换 ES6代码
- 【优化算法】蜻蜓算法(DA)【含Matlab源码 1306期】
- xp系统怎样安装传真服务器,Windowsxp系统下设置传真接收的详细步骤
- 基于fpga+stm32的数字示波器
- DotSoft.C3DTools.v7.0.0.3民用勘测地图和GIS工具集合
- JavaScript 每日一题 #8
- npm cb() never called!和 Error: getaddrinfo ENOTFOUND registry.npmjs.com registry.npmjs.com:443
- MySQL常用命令与函数
- 第十周 项目一 计算税后收入
- 域名备案申请未通过管局审核,因为在审核通过前网站已开通
- 观周鸿祎先生访谈之后感
- 用ul、li做横向导航
- 深度学习-skimage.transform报错的玄学问题
- js求两个数的百分比
- Kanzi学习教程培训教程-Kanzi的简介和安装
- 【实用】JavaScript中Video使用详解过程(多视频列表循环播放)
热门文章
- jsp用javascript关于浏览器静止后退,刷新
- JavaScript编写计算器-《JavaScript王者归来》读书笔记1
- 常用 MySQL 操作
- MySQL 启动服务和登陆参数
- HDU2093--考试排名
- linux下添加vnc
- 【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置***帧以及动画创建!【二】...
- 让人等不及的潮州小吃“来不及”
- 转成静态页面,由于ie网址或路径原因,Atlas失效。
- android各版本对应的SDK level(包括android 10)