- 浏览: 369873 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
参考
http://blog.csdn.net/insistgogo/article/details/6653301
多继承的定义:派生类的基类大于一个
语法:
多重继承与构造函数的关系:
多重继承时构造函数的作用:
1)初始化派生类(自己)
2)调用该派生类所有基类构造函数,并且为所有基类传参(参数个数必须包含所有基类所需参数)
构造函数语法:
说明:派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用;如果未列出,则表示使用该虚基类的缺省构造函数。
具体点来说:初始化列表中要包括对 直接基类 + 虚基类 进行调用。
构造函数的执行次序(不含虚基类):
(1)基类:依派生的次序决定,与构造函数中书写顺序无关
(2)子对象的构造函数
(3)派生类的构造函数
析构函数的执行次序:和上述执行顺序相反
注意:
1)析构函数能继承;
2)派生类中要定义自己的析构函数释放在派生中新增的成员;
3)从基类中继承的成员释放,可以通过基类的析构函数实现;
4)激活析构函数的顺序与构造函数缴活顺序相反。
举例:
说明:继承/多重继承一般是公有继承,保护继承/私有继承只是在技术讨论较多,实际使用较少。
多继承中同名覆盖原则
当派生类与基类中有同名成员时:
调用派生类的成员:定义派生类对象,直接调用同名函数即可,而自动屏蔽基类的同名函数。
访问基类中成员:应使用基类名限定。
举例:
多继承带来的二义性:
当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性
即:派生类从同一个基类,沿不同继承方向,得到多个相同的拷贝,不知道要访问哪一个,就产生了二义性。
二义性的常用解决方法:使用作用域运算符(类名::)来解决访问二义性问题使用访问,但是这里的成员都是来源于同一个基类,这时是不能解决问题的,这里就引入虚基类
虚基类:
虚基类的作用:使公共基类只产生一个拷贝,即只对第一个调用的有效,对其他的派生类都是虚假的,没有调用构造函数
使用场合:用于有共同基类的场合
原理:让虚基类的构造函数只执行一次,派生类只得到一套虚基类的成员
语法:
注意:声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次
虚基类的初始化:与一般多继承的初始化在语法上是一样的,但构造函数的调用次序不同.
派生类构造函数的调用次序:(先虚基类,后基类,再成员对象,最后自身)
(1)对虚基类间的构造函数的顺序:根据虚基类间继承的顺序调用
(2)对基类间的构造函数的顺序:根据基类间继承的顺序调用
(3)对成员对象的构造函数的顺序:根据成员对象在类中声明顺序调用
(4)若同一层次中包含多个虚基类,这些虚基类的构造函数按它们说明的次序调用;
(5)若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类的构造函数.
举例:
将产生如下调用次序:
说明:
1)D是A的虚基类,故先调用D的构造函数
2)在同层次的多个虚基类中,从左到右调用,先B到C
3)基类构造函数调用完后,在调用A的构造函数
举例:使用虚基类和不使用虚基类的说明:
错误代码:
基类的层次图:
正确代码:
使用虚基类后的层次图:
注意:
1、派生类构造函数初始化列表对虚基类的处理:
有虚基类和没费基类两种情况下,派生类构造函数的书写情况是不一样的,上面注释有代码。
没有虚基类的多继承,派生类构造函数的声明只包括其直接的基类
有虚基类的多继承,派生类构造函数的声明不仅包含其直接基类还要包含直接基类的虚基类。
2、
1)运行时,C创建对象时,先找到直接基类B1,调用直接基类B1的构造函数时,又调用A的构造函数,无基类,直接调用
2)之后,在调用B1的构造函数,之后再调B2的构造函数时,发现有基类A,但是A为虚基类,已经调用过一次,不再调用
3)之后,直接调用B2的构造函数,完了,就直接调用C的构造函数
说明:
1、虚基类怎么保证初始化派生类对象时,只被调用一次?
因为:初始化列表中要包括对 直接基类 + 虚基类 进行调用,但仅仅用建立对象的最远派生类的构造函数调用虚基类的构造函数,而该派生类的所有基类中列出的对虚基类的构造函数的调用在执行中被忽略,即对其他基类来说,这个基类是虚假的,而不再调用虚基类,从而保证对虚基类子对象只初始化一次。
2、一个类可以在一个类族中既被用作虚基类,也被用作非虚基类。
http://blog.csdn.net/insistgogo/article/details/6653301
多继承的定义:派生类的基类大于一个
语法:
class 派生类名:继承方式1 基类名1,继承方式2 基类名2... { <派生类新定义成员> };
多重继承与构造函数的关系:
多重继承时构造函数的作用:
1)初始化派生类(自己)
2)调用该派生类所有基类构造函数,并且为所有基类传参(参数个数必须包含所有基类所需参数)
构造函数语法:
派生类构造函数名(总参数表列): 基类1构造函数(参数表列), 基类2构造函数(参数表列), 基类3构造函数(参数表列) { //派生类中新增数成员据成员初始化语句 }
说明:派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用;如果未列出,则表示使用该虚基类的缺省构造函数。
具体点来说:初始化列表中要包括对 直接基类 + 虚基类 进行调用。
构造函数的执行次序(不含虚基类):
(1)基类:依派生的次序决定,与构造函数中书写顺序无关
(2)子对象的构造函数
(3)派生类的构造函数
析构函数的执行次序:和上述执行顺序相反
注意:
1)析构函数能继承;
2)派生类中要定义自己的析构函数释放在派生中新增的成员;
3)从基类中继承的成员释放,可以通过基类的析构函数实现;
4)激活析构函数的顺序与构造函数缴活顺序相反。
举例:
#include <iostream> using namespace std; class A { public: A() { cout<<"调用A的构造函数"<<endl; } }; class B { public: B() { cout<<"调用B的构造函数"<<endl; } }; class C:public A,public B //这里声明顺序决定了调用基类的顺序 { private: A a; public: C() { cout<<"调用C的构造函数"<<endl; } }; void main() { C c; system("pause"); }
调用A的构造函数--C的基类 调用B的构造函数--C的基类 调用A的构造函数--C的对象成员 调用C的构造函数--C自己的构造函数
说明:继承/多重继承一般是公有继承,保护继承/私有继承只是在技术讨论较多,实际使用较少。
多继承中同名覆盖原则
当派生类与基类中有同名成员时:
调用派生类的成员:定义派生类对象,直接调用同名函数即可,而自动屏蔽基类的同名函数。
访问基类中成员:应使用基类名限定。
举例:
#include<iostream> using namespace std; class A { public: void f() { cout<<"调用A的构造函数"<<endl; } }; class B { public: void f() { cout<<"调用B的构造函数"<<endl; } }; class C:public A,public B { public: void f() { cout<<"调用C的构造函数"<<endl; } }; void main() { C c; c.f();//覆盖基类中f函数 c.B::f();//通过基类名限制访问 c.A::f(); system("pause"); }
多继承带来的二义性:
当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生二义性
即:派生类从同一个基类,沿不同继承方向,得到多个相同的拷贝,不知道要访问哪一个,就产生了二义性。
二义性的常用解决方法:使用作用域运算符(类名::)来解决访问二义性问题使用访问,但是这里的成员都是来源于同一个基类,这时是不能解决问题的,这里就引入虚基类
虚基类:
虚基类的作用:使公共基类只产生一个拷贝,即只对第一个调用的有效,对其他的派生类都是虚假的,没有调用构造函数
使用场合:用于有共同基类的场合
原理:让虚基类的构造函数只执行一次,派生类只得到一套虚基类的成员
语法:
class 派生类名:virtual 继承方式 类名 //在派生类定义的时候写。 { }
注意:声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次
虚基类的初始化:与一般多继承的初始化在语法上是一样的,但构造函数的调用次序不同.
派生类构造函数的调用次序:(先虚基类,后基类,再成员对象,最后自身)
(1)对虚基类间的构造函数的顺序:根据虚基类间继承的顺序调用
(2)对基类间的构造函数的顺序:根据基类间继承的顺序调用
(3)对成员对象的构造函数的顺序:根据成员对象在类中声明顺序调用
(4)若同一层次中包含多个虚基类,这些虚基类的构造函数按它们说明的次序调用;
(5)若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类的构造函数.
举例:
class A : public B, public C,virtual public D {} X one;
将产生如下调用次序:
D() B() C() A()
说明:
1)D是A的虚基类,故先调用D的构造函数
2)在同层次的多个虚基类中,从左到右调用,先B到C
3)基类构造函数调用完后,在调用A的构造函数
举例:使用虚基类和不使用虚基类的说明:
错误代码:
#include<iostream> using namespace std; class A { protected: int a; public: A(int a) { this->a=a; } }; class B1: public A { public: B1(int a):A(a) { } }; class B2: public A { public: B2(int a):A(a) { this->a=a; } }; class C:public B1,public B2 { public: C(int a):B1(a),B2(a) //没有使用虚基类,声明时,只写C的直接基类B1和B2,不写虚基类构造函数A { } void display() { cout<<"a="<<a<<endl;//使用A::a区分也不行,这里的a是从A得到的,B1和B2都继承到了,到D中就有两份拷贝,都来自A产生歧义 } }; void main() { D d(1); d.display(); system("pause"); }
基类的层次图:
正确代码:
#include<iostream> using namespace std; class A { protected: int a; public: A(int a) { this->a=a; } }; class B:virtual public A { public: B(int a):A(a) { } }; class C:virtual public A { public: C(int a):A(a) { this->a=a; } }; class D:public B,public C { public: D(int a):B(a),C(a),A(a)//使用虚基类,声明时是 D的直接基类B和C + 直接基类的共同基类A { } void display() { cout<<"a="<<a<<endl; //使用虚基类时,A只执行一次,调用B的时候调用一次虚基类,调用C时,就没有调用A了,D中的a也只有一个拷贝,因而不产生歧义 } }; void main() { D d(1); d.display(); system("pause"); }
使用虚基类后的层次图:
注意:
1、派生类构造函数初始化列表对虚基类的处理:
有虚基类和没费基类两种情况下,派生类构造函数的书写情况是不一样的,上面注释有代码。
没有虚基类的多继承,派生类构造函数的声明只包括其直接的基类
有虚基类的多继承,派生类构造函数的声明不仅包含其直接基类还要包含直接基类的虚基类。
2、
1)运行时,C创建对象时,先找到直接基类B1,调用直接基类B1的构造函数时,又调用A的构造函数,无基类,直接调用
2)之后,在调用B1的构造函数,之后再调B2的构造函数时,发现有基类A,但是A为虚基类,已经调用过一次,不再调用
3)之后,直接调用B2的构造函数,完了,就直接调用C的构造函数
说明:
1、虚基类怎么保证初始化派生类对象时,只被调用一次?
因为:初始化列表中要包括对 直接基类 + 虚基类 进行调用,但仅仅用建立对象的最远派生类的构造函数调用虚基类的构造函数,而该派生类的所有基类中列出的对虚基类的构造函数的调用在执行中被忽略,即对其他基类来说,这个基类是虚假的,而不再调用虚基类,从而保证对虚基类子对象只初始化一次。
2、一个类可以在一个类族中既被用作虚基类,也被用作非虚基类。
- C__多继承与虚基类.zip (49.5 KB)
- 下载次数: 0
发表评论
-
FreeRTOS
2022-03-05 16:31 248Ref https://blog.csdn.net/weix ... -
串口通讯相关
2018-11-02 13:44 411https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1325https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 477https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 574// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 580https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 5738583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 600参考link http://www.cnblogs.com/l ... -
C++实现ping功能
2017-04-18 11:21 2155基础知识 ping的过程是向目的IP发送一个type=8的I ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 9061 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1582OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1881ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 871转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1908转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 1086C++编写标准Win32DLL如下 头文件 /***** ... -
C#调用C++的DLL搜集整理的所有数据类型转换方式
2016-09-09 16:07 969转自 http://www.cnblogs.com/zeroo ... -
WinCE CPU使用率计算 测试工具
2016-09-08 16:14 991转自 http://blog.csdn.net/jan ... -
switch在C++与C#中的一些差异
2016-09-08 15:19 810参考链接 http://blog.csdn.net/weiwe ... -
C++ 鼠标模拟程序
2016-09-04 12:09 1612转自 http://blog.csdn.net/weixinh ...
相关推荐
1, 设计一个人员基类person类,包括描述基本信息的数据成员,提供基本操作的函数成员以及析构函数和不同形式的构造函数
在C++编程语言中,数据...总的来说,C++的虚函数和虚基类提供了强大的多态性和继承解决方案,让程序员能够创建复杂的面向对象系统,而无需担心类型转换的困扰。理解并熟练掌握这些特性,对于提升C++编程能力至关重要。
本资源总结了C++中的多继承和虚基类的概念和应用。多继承是指一个派生类可以继承多个基类的成员,包括数据成员和函数成员。虚基类是解决多继承中出现的命名冲突和继承路径复杂性的机制。 多继承 多继承是指一个...
虚基类与虚函数是C++中面向对象编程的关键特性,它们主要解决多继承带来的问题。在C++中,一个类可以作为多个派生类的基类,这可能导致同一个基类在派生类中出现多次,即所谓的"菱形继承"问题。为了解决这种情况下的...
"C++继承与派生虚基类" 本文主要讨论C++中的继承和派生虚基类,通过实验设计方案,实验内容和实验步骤,来详细介绍虚函数、抽象基类、多态性和文件输入输出的概念。 一、实验设计方案 实验名称:类和类的继承 ...
在C++中,虚基类主要用于解决多继承中的钻石问题(即多个派生类继承自同一个基类,而这些派生类又被另一个类继承,形成一个钻石形状的继承结构)。当一个类同时继承自两个或更多的具有相同基类的类时,如果没有使用...
当一个类从两个或更多具有共同基类的类继承时,如果没有使用虚基类,那么基类的实例会被每个派生类复制一次,可能导致数据冗余。通过声明基类为虚基类(using `virtual` 关键字),可以确保只有一个基类实例存在,...
从bicycle和motorcar派生出motorcycle,观察虚基类对继承的影响。 定义一个motorcycle的对象,分别调用run()和stop(),观察构造/析构函数的调用情况。 注意:构造函数和析构函数中均为cout语句,说明哪个构造/析构...
C++是一种强大的面向对象编程语言,它提供了许多高级特性,如虚函数、虚基类、对象实例化以及运算符重载。这些特性使得C++在处理复杂问题时具有极高的灵活性和可扩展性。 首先,我们来探讨**虚函数**。在C++中,虚...
在这个“继承派生虚基类.rar”实验中,我们将探讨C++中的继承机制,特别是虚基类的使用,以及如何处理多继承和连续继承的情况。这个实验涉及到了大学计算机科学课程中常见的主题,对于理解和掌握C++的面向对象特性至...
定义一个Person 类,结构如下图,为该类添加输入输出流运算符重载。Person 类以Public方式派生出一个Teacher类,数据成员包括:int gh(工号);char* title(职称),为该类添加输入输出流运算符重载,完成有参、无参、...
在C++编程中,多重继承和虚基类是两种重要的特性,它们允许一个类可以从多个父类中继承属性和行为。Visual Studio 2008(VS2008)作为一个强大的开发环境,支持这些高级的面向对象特性,使得开发者能够创建复杂的...
本文分两部分即继承和虚函数与多态性,本文第一部分详细讲解了继承时的构造函数和析构函数的问题,父类与子类的 同名变量和函数问题,最后介绍了多重继承与虚基类。本文第二部分重点介绍了虚函数与多态性的问题,...
多继承下的派生类构造函数必须同时负责该派生类的所有基类构造函数的参数传递。且构造函数和析构函数的调用顺序和单继承是一样的,先调用基类构造函数,再调用对象成员的构造函数,最后调用派生类的构造函数。那么...
虚基类与虚函数 虚基类的概念 在C++语言中,一个类不能被多次说明为一个派生类的直接基类,但可以不止一次地成为间接基类。这就导致了一些问题。为了方便 说明,先介绍多继承的“类格”表示法。
"C++面向对象程序设计习题继承与派生.pdf" 继承是面向对象程序设计中的一种重要机制,它允许一个类继承另一个类的属性和行为特征。通过继承,新类可以从现有类中获得特征,从而达到代码复用的目的。在C++中,继承...
3. **构造函数与析构函数**:由于虚基类可能在多个派生类中被初始化,因此必须确保DLL中的构造函数和析构函数能够正确处理这种情况。通常,基类的构造函数应该是虚的,以便在派生类的构造函数中调用。 4. **内存...