多重继承的二义性以及解决方法
来源:互联网 发布:ip端口扫描器 dos版本 编辑:程序博客网 时间:2024/06/05 17:12
//多重继承的二义性以及解决方法
//学习目的:了解类的继承原理及多重继承二义性的解决方法。
/*
//本程序代码来源《MFC权威剖析》p68
*/
////////////////////第一种多重继承的二义性////////////////
class Employee
{
public:
char Name[40];
bool Sex;
};
class Worker : public Employee
{
};
class Manager : public Employee
{
};
class Engineer : public Worker, public Manager
{
};
//Engineer的实例化对象内存中包含两个Employee子对象,分别属于Worker和Manager子对象,
//这样在该实例的内部就封装了两套员工个人档案,显然是错误的。
{
Engineer eng;
eng.Worker::Sex = true;
eng.Manager::Sex = false;//eng的性别即使男又是女
}
/////////////////////解决办法////////////////////////
//在父类存在共同双亲的情况下,可以通过虚拟基类来解决。
//虚拟基类的作用是:如果在一个派生类的继承结构中,存在两个同样的虚拟基类,那么
//该类的实例化对象内存中只存在一个虚拟基类的子对象。
//事例
class Employee
{
public:
char Name[40];
bool Sex;
};
class Worker : public virtual Employee //Employee
{
};
class Manager : public virtual Employee //Employee
{
};
class Engineer : public Worker, public Manager
{
};
//这样的继承方式,虚拟基类的子对象不再包含在每个父类中,而是单独存在。
//父类对象中存在一个指向其虚拟父类子对象的一个指针,该指针被称为虚父类指针,
//由编译器生成。这样就保证了在多重继承时,子类实例中只存在一个虚拟基类的子对象。
//但同名的非虚拟基类的子对象没有被合并。
/////////////////////第二种多重继承的二义性////////////////
class ParentA
{
public:
void fun() {printf("%d\n", m_Value); };
private:
int m_Value;
};
class ParentB
{
public:
void fun() {printf("%d\n", m_Value); };
private:
int m_Value;
};
class Son : public ParentA, public ParentB
{
};
///////////////////////解决办法////////////////////////
//在父类没有共同双亲的情况下,一般在子类中将名字冲突的成员重新定义,
//以此解决二义性。
/////////////////////////////使用虚拟基类需要注意的问题////////////
#include "stdio.h"class Base{public: Base(){printf("Base is constructed as default\n");} Base(int i) { m_iValue=i; printf("Base is constructed in constructing list\n"); } ~Base(){printf("Base is deconstructed\n");} int GetiValue()const { return m_iValue; }private: int m_iValue;};class ParentA :public virtual Base{public: ParentA(){} ParentA(int i,float f):Base(i) { m_fValue=f; } float GetfValue()const { return m_fValue; }private: float m_fValue;};class ParentB :public virtual Base{public: ParentB(){} ParentB(int i,char c):Base(i) { m_cValue=c; } char GetcValue()const { return m_cValue; }private: char m_cValue;};class Son:public ParentA,public ParentB{public: Son(int i,float f,char c):ParentA(i,f),ParentB(i,c) { } void Output() { printf("son member is %d %8.2f %c\n", GetiValue(),GetfValue(),GetcValue()); }};int main(int argc, char* argv[]){ Son son(6,92.33,'D'); son.Output(); return 0;}/*输出Base is constructed as defaultson member is -858993460 92.33 Dase is deconstructed*///由程序输出可以看出,虚拟基类只被构造一次,销毁一次,所以只存在一个子对象。//但Base基类被调用的是默认构造函数,ParentA和ParentB对虚拟基类的构造无效。//其实,为了保证虚拟基类只被构造一次,虚拟基类的构造函数不能按照传统的方式调用,//即不能被直接子类调用,而是由当前最底层次类的构造函数调用,该类被称为最派生类。//道理其实很简单,和虚函数原理是一样的。//如果将Son的构造函数改成:Son(int i, float f, char c):ParentA(i, f),ParentB(i, c),Base(i){}/*则输出Base is constructed as defaultson member is 6 92.33 Dase is deconstructed*/
//应用虚拟基类虽然解决了基类子对象重复问题,但还不能完全消除二义性的可能。
//如果两个直接父类同时定义了同名的函数,则还会产生二义性。
- 多重继承的二义性以及解决方法
- 多重继承的二义性以及解决方法
- 多重继承以及多重继承中二义性的解决:虚基类
- c/c++ 多重继承下的二义性解决方法
- 多重继承引发的二义性问题及解决方法分析
- 关于继承,多重继承,以及虚拟类
- c++远征之继承篇——多重继承,多继承,虚继承,多继承时的重复定义解决方法
- 多重继承引起的二义性问题
- 多重继承的基本概念
- 多重继承的优缺点
- C++的多重继承
- 多重继承的优缺点
- 多重继承的优缺点
- 多重继承的优缺点
- 类的多重继承
- C++的多重继承
- python的多重继承
- python的多重继承
- 在Hadoop上运行SQL:程序员需知晓的13种数据工具
- JAVA中常用英文简写全拼及中文含义
- php 2
- php 3
- taobao 错误码一览表补充的
- 多重继承的二义性以及解决方法
- [LeetCode] 无序数组中的最长连续数列 The Longest Consecutive Sequence in an unsorted array
- php 4
- java连接telnet进行操作
- Zxing2.1完美竖屏扫描,取景框不会变形哦!
- php 5
- php 6
- 人民币大写源码
- php 7