-
2017-03-20 23:13:10多重继承容易造成二义性(比如同时从两个类继承了函数名一样的函数,到底调用哪一个),解决方式是在调用的函数之前加上想用的类名::(d.A::hello()//调用从A类继承来的那个hello函数)。更多相关内容
-
C++基础知识 - 多重继承的二义性问题
2022-02-17 20:57:30多重继承的二义性就是在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——同名二义性 当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,...什么是二义性?
- 简单来说就是一个班级有两个同名的人都叫张三, 老师叫张三回答这道题, 这时, 谁都不知道老师指的是哪个张三, 这就是二义
- 多重继承的二义性就是在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——同名二义性
- 当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生另一种不确定性——路径二义性。
demo
#include <iostream> #include <Windows.h> using namespace std; class Father { public: Father() {} ~Father() {} void play() {cout << "Father KTV唱歌!" << endl;} }; class Mother { public: Mother() {} ~Mother() {} void play() {cout << "Mother 逛街购物!" << endl;} }; class Son : public Father, public Mother{ public: Son() {} ~Son() {} }; int main(void) { Son son; son.play(); //无法确定该调用Fther的play()还是Mother的play() system("pause"); return 0; }
解决多重继承的二义性的方法1:
使用 “类名::” 进行指定, 指定调用从哪个基类继承的方法!
son.Father::play(); son.Mother::play();
解决多重继承的二义性的方法2:
在子类中重新实现这个同名方法, 并在这个方法内部, 使用基类名进行限定,
来调用对应的基类方法class Son : public Father, public Mother{ public: Son() {} ~Son() {} void play() { Father::play(); Mother::play(); } }; int main(void) { Son son; son.play(); //调用自己类内部重写的play()方法 system("pause"); return 0; }
-
C++多重继承二义性原理实例解析
2020-12-17 03:35:13在派生类中对基类成员访问应该是唯一的,但是在多继承时,可能会导致对基类某成员访问出现不一致的情况,这就是C++多继承中的二义性。 有两种继承的情况会产生多义性 一、如果一个派生类从多个基类派生,而这些基类... -
C++ 中多继承和多重继承的二义性坑
2022-05-09 20:30:52多继承可能存在二义性问题:即如果继承的父类中出现同样的方法或者数据的时候,那么当子类去调用的时候会存在不知道调用谁的问题。 有问题的代码: #include <iostream> using namespace std; class ...多继承
多继承:一个子类可能有多个父类(基类)。
多继承可能存在二义性问题:即如果继承的父类中出现同样的方法或者数据的时候,那么当子类去调用的时候会存在不知道调用谁的问题。
有问题的代码:
#include <iostream> using namespace std; class A { public: A() { } ~A() { } void play() { cout << "AAA" << endl; } protected: int age = 12; }; class B { public: B() { } ~B() { } void play() { cout << "BBB" << endl; } protected: int age = 13; }; class C: public A, public B { public: C() { } ~C() { } void test() { cout << age << endl; // 存在二义性问题,编译器不知道该调用那个父类的 } }; int main() { C c1; c1.play(); // 存在二义性问题,编译器不知道该调用那个父类的 }
多继承二义性的解决方法:
1、子类访问父类成员数据可以指定父类名
2、子类访问父类方法可以指定父类名或者重写方法再调用父类方法
#include <iostream> using namespace std; class A { public: A() { } ~A() { } void play() { cout << "AAA" << endl; } protected: int age = 12; }; class B { public: B() { } ~B() { } void play() { cout << "BBB" << endl; } protected: int age = 13; }; class C: public A, public B { public: C() { } ~C() { } // 优雅的访问父类方法 void play() { A::play(); B::play(); } void test() { cout << A::age << endl; // 访问父类成员可以指定父类名 } }; int main() { C c1; c1.test(); c1.play(); // 存在二义性问题,编译器不知道该调用那个父类的 c1.A::play(); // 这种方法也可以不推荐 return 0; }
输入、输出:
多重继承
多重继承:A的派生类B和C,B和C的派生类为D类。
多重继承(菱形继承)存在的问题也是二义性,当D类同时继承B和C的时候,那么该类中会同时存在两个同名的数据成员,分别属于B类和C类的。
解决法:
1、指定父类名
2、通过虚继承的方式解决
问题代码:
#include <iostream> using namespace std; class A { public: A() { } ~A() { } protected: int age = 12; }; class B : public A { }; class C : public A { }; class D : public B, public C { public: void test() { age = 12; // 问题代码,存在歧义 } }; int main() { D d1; d1.test(); return 0; }
通过VS命令行参数查看对象的内存分布:
命令参数:/d1 reportSingleClassLayoutD
输出的内存分布:
可以看到内存分布中存在两个age
使用虚基类解决:
#include <iostream> using namespace std; class A { // 虚基类 public: A() { } ~A() { } protected: int age = 12; }; class B: virtual public A { // 虚继承 }; class C : virtual public A { // 虚继承 }; class D : public B, public C { public: void test() { age = 13; cout << age << endl; } }; int main() { D d1; d1.test(); return 0; }
再次查看内存分布图其中只有一个数据
-
c++中多重继承二义性产生以及二义性的消除方法
2019-11-20 23:07:09由此c++引入了,多重继承的概念,也就是允许一个派生类指定多个基类,这样就被叫做多重继承。 如下代码: #include "stdafx.h" #include <iostream> #pragma warning(disable:4996) #include <string>...实际的业务场景中,一些事物会有多个属性。由此c++引入了,多重继承的概念,也就是允许一个派生类指定多个基类,这样就被叫做多重继承。
如下代码:
#include "stdafx.h" #include <iostream> #pragma warning(disable:4996) #include <string> using namespace std; class car{ public: car(){ cout << "this is car" << endl; } void print(void) { cout << "car class print" << endl; } }; class truck:public car { public: truck(){ cout << "this is truck" << endl; } void truck_print(void){ cout << "truck::truck_print" << endl; } }; class bus:public car { public: bus(){ cout << "this is bus" << endl; } void bus_print(void){ cout << "bus::bus_print" << endl; } }; class train :public truck, public bus{ public: train(){ cout << "this is train" << endl; } void train_print(void){ cout << "train::train_print" << endl; } }; int main(int argc, char *argv[]) { train test1;//多重继承的构造顺序和继承列表中基类的排列顺序一致,不是和它的初始化列表中的顺序 //一致,所以先执行truck中的构造函数,truck先执行car的构造函数。再执行bus中的构造函数,bus中先执行 //car中的构造函数 /*this is car this is truck this is car this is bus this is train*/ test1.train_print();//train::train_print test1.truck_print();//truck::truck_print test1.print();//出现二义性,print成员函数不明确。因为类bus和truck继承car的时候,都分别对 //car中的成员函数print做了一份拷贝。train在继承bus和truck时对bus和truck多了拷贝。所以 //test1.print()无法访问那个基类的print。 car *p_car = &test1;//同样会产生二义性,将上面的继承按照下面的方法二,改为虚继承即可。 return 0; }
消除二义性的方法:
1.加上全局符指定使用哪一份拷贝。如:
test1.truck::print(); test1.bus::print();
2.使用虚继承,这样的话。派生类train只有一份基类car的拷贝了。如:
将上面的
class truck:public car
class bus:public car
改为:
class truck:virtual public car
class bus:virtual public car
-
C++中多重继承的二义性及解决办法
2017-10-11 17:00:52转自:... 1. 什么是多重继承的二义性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 cla -
C++多继承中的二义性问题
2018-05-24 17:35:46在C++中,派生类继承基类,对基类成员的访问应该是确定的、唯一的,但是常常会有以下情况导致访问不一致,产生二义性。 1.在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——... -
多重继承的二义性以及解决方法
2016-07-24 16:07:24//多重继承的二义性以及解决方法 //学习目的:了解类的继承原理及多重继承二义性的解决方法。 /* //本程序代码来源《MFC权威剖析》p68 */ ////////////////////第一种多重继承的二义性//////////////// ... -
C++学习(49):多重继承二义性、虚基类
2020-08-19 19:12:36示例代码: #include<...//虚拟继承 class B : virtual public A { public: B() { a = 200; } }; //虚拟继承 class C : virtual public A { public: C() { a = 300; } }; class D : public B -
多重继承引发的二义性问题及解决方法分析
2017-06-07 22:15:26 ...多重继承:一个类派生出多个类,多个类派生出一个类 性质与规则: 1.声明方法:class D:public A,private B,protected C{} 2.调用顺序:先调用A的构造函数,再到B,再到C。虚基类->非虚基 -
多重继承——菱形继承(二义性)
2016-05-11 14:28:38菱形继承的定义如下,从Base出发,至AB汇合,因此成为菱形继承。 class Base; class SubA : public Base; class SubB : public Base; class AB : ... 1.二义性 , 如果 Base定义了一个函数 fun, 在 -
C++多重继承及多态性原理实例详解
2020-08-18 22:47:02主要介绍了C++多重继承及多态性原理实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
多重继承的弊端:二义性[多重继承的钻石问题]
2022-05-18 23:25:30二义性: Father.h Father.cpp Mother.h Mother.cpp Son.h Son.cpp main.cpp 总结: C++中const char * const name;char * const name;const char * name三者之间的区别? [知识点] 多继承/多重继承: ... -
(36.1)多重继承之多重继承派生类及二义性问题
2020-02-02 21:41:19二义性问题 1.多重继承派生类 除去一个类从一个基类派生, C++还支持一个派生类同时继承多个基类。 这样理解:子女既可以继承父亲的特点,也可以继承母亲的特点 多重继承派生类的定义 如果已经定义了多个基类, ... -
多继承的二义性
2018-10-08 09:45:22多继承的二义性主要分为两种: 调用不同基类的同名成员时可能出现二义性 访问共同基类的成员可能出现二义性 1、调用不同基类的同名成员时可能出现二义性 class A { public: void setA(int a); int get(); ..... -
C++多继承的二义性问题.pdf
2020-10-30 02:12:26C++ 多继承的二义性问题 在多重继承中需要解决的主要问题是标识符不唯一即二义性问题比如 当在派生类继承的多个基类中有同名成员时派生类中就会出现标识符不唯一的情况 在多重继承中派生类由多个基类派生时基类之间... -
多重继承二义性
2018-06-10 02:05:20先以一个例子来引入多重继承出现的问题:#include <iostream>using namespace std;class Person{ public : void sleep(){cout<<"this is a sleep function"<<... -
【C++_10】多重继承与虚继承(定义方法、构造和析构函顺序、二义性、重复继承、虚拟继承)
2022-05-04 14:05:44文章目录多重继承的定义方法多重继承的构造、析构顺序多重继承中的二义性虚拟继承虚拟继承的构造顺序 多重继承的定义方法 如果在定义一个派生类时,该派生类继承了2个或2个以上基类的特征,那么这种继承关系就称为... -
多重继承以及多重继承中二义性的解决:虚基类
2017-06-08 17:24:39多重继承:一个派生类有两个或多个基类,派生类从两个或多个基类中继承所需的属性。 多重继承要和多级派生区分,多级派生是指一个类派生出一个子类,这个子类再派生出另一个子类,以此类推。 对于多重继承,c++... -
多继承的二义性和虚继承(虚基类)
2017-09-04 16:22:29但是,由于在多继承的情况下,可能出现基类中某个成员的访问不唯一的情况,这称为对基类成员访问的二义性。在多继承的情况下,通常有两种可能出现的二义性。 1 派生类的多个基类中调用其同名成员时可能出现二义性... -
c++之多继承中的二义性
2020-06-04 21:44:35转载C++:多继承中的二义性问题 在派生类中对基类成员的访问应该是唯一的.但是,在多继承情况下,可能造成对基类中某个成员的访问出现了不一致的情况,这时就称对基类成员的访问产生了二义性. 原因一、 派生类在访问... -
多重继承的二义性问题
2021-05-08 20:56:16可参考:派生类构造函数和多重继承的二义性问题 -
C++继承——多继承(二义性)
2020-05-06 22:19:56前言:一个派生类只有一个基类,叫做单继承 一个派生类可以有两个或多个...在多继承形式下的构造函数和单继承形式基本相同,就是在派生类的构造函数的初始化列表中调用多个基类的构造函数 class D:public A,publi... -
C++多继承带来的二义性问题的解决方案
2021-03-04 10:56:48多继承(菱形或称钻石继承)编程可以带来很多便利,也更贴近生活但也带来很多麻烦 #include<iostream> using namespace std; class B1 { public: void output(); }; class B2 { public: void output(); };... -
虚基类与多重继承的二义性
2022-02-11 11:38:31C++多重继承的二义性 - 知道了呀~ - 博客园 -
派生类构造函数和多重继承的二义性问题
2015-09-06 11:55:55一、派生类构造函数的写法(1)冒号...(2)需要注意的是:冒号后面是对基类构造函数的调用,而不是声明,所以括号里的参数是实参二、基类构造函数调用规则(1)通过派生类创建对象时必须要调用基类的构造函数,这是 -
学习笔记(11):C++语言基础视频教程-5.7 多重继承中二义性的解决
2020-03-01 10:59:56本教程详细介绍C++语言中的封装、数据隐藏、继承、多态的实现等入门知识;主要包括类的声明、对象定义、构造函数和析构函数、运算符重载、继承和派生、多态性实现等。 课程需要有C语言程序设计的基础(可以利用本人... -
C++ 多重继承
2021-01-20 13:39:42注意:多重继承在实际开发中尽量少用,能不用就不用。多重继承很繁杂,很复杂。 多重继承就是派生类继承多个基类,继承方法和一个继承是一样的。 一个继承请看我 —> “C++ 继承和派生” 文章,会有详细介绍。 链接:...
收藏数
12,208
精华内容
4,883