精华内容
下载资源
问答
  • 2018-10-08 09:45:22

    转自:https://www.cnblogs.com/tenjl-exv/p/7625484.html

    多继承的二义性主要分为两种:

    1. 调用不同基类的同名成员时可能出现二义性
    2. 访问共同基类的成员可能出现二义性

    1、调用不同基类的同名成员时可能出现二义性

    class A
    {
        public:
            void setA(int a);
            int get();
        private:
            int a;
    } ;
    class B
    {
        public:
            void setB(int b);
            int get();
        private:
            int b;
    } ;
    
    class C:public A,public B
    {
        public:
            void setC(int c);
            int getC();
        private:
            int c;
    };

     在执行obj.get();时将是有二义性的。因为类C分别从类A类B继承了两个不同版本的get()成员函数,因此,obj.get();到底调用哪个get()版本,编译器将无从知晓。

    有两种解决方法:

    (1)使用作用域分辨符::加以消除。

    obj.A::get();

    obj.B::get();

    (2)在类C中也定义成员函数get()函数,则有类C的对象obj访问get()函数obj.get()没有二义性,这是因为当派生类中的成员与基类中的成员重名时,派生类中的同名成员将被调用。

    class A
    {
        public:
            void setA(int a);
            int get();
        private:
            int a;
    } ;
    class B
    {
        public:
            void setB(int b);
            int get();
        private:
            int b;
    } ;
    
    class C:public A,public B
    {
        public:
            void setC(int c);
            int get();
                    //此处改为这样    
        private:
            int c;
    };

     2、访问共同基类的成员可能出现二义性

    菱形继承问题

    class A
    {
        public:
            void disp(); 
        private:
            int a;
    };
    
    class B1:public A
    {
        public:
            void dispB1();
        private: 
            int b1;
    };
    class B2:public A
    {
        public:
            void dispB2();
        private: 
            int b2;
    };
    
    class C:public B1,public B2
    {
        public:
            void dispC();
        private: 
            int c;
    };

     

    在此类结构下,如果创建类C的对象c1:

    C c1;

    则下面的两个访问都有二义性:

    c1.disp();

    c1.A::disp();

    不过下面的两条调用语句却是正确的:

    c1.B1::disp();

    c1.B2::disp();

    解决方法:

    采用虚基类的方式,代码如下:

    class A
    {
        public:
            void disp(); 
        private:
            int a;
    };
    
    class B1:virtual public A
    {
        public:
            void dispB1();
        private: 
            int b1;
    };
    class B2:virtual public A
    {
        public:
            void dispB2();
        private: 
            int b2;
    };
    
    class C:public B1,public B2
    {
        public:
            void dispC();
        private: 
            int c;
    };

     

    更多相关内容
  • C++多继承中的二义性问题

    千次阅读 多人点赞 2018-05-24 17:35:46
    在C++中,派生类继承基类,对基类成员的访问应该是确定的、唯一的,但是常常...当派生类从个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生另一种不确定性——路径二义性。 1. ...
        在C++中,派生类继承基类,对基类成员的访问应该是确定的、唯一的,但是常常会有以下情况导致访问不一致,产生二义性。
        1.在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——同名二义性。
        2.当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生另一种不确定性——路径二义性。

        1.

                                                                        

    “倒三角”问题——同名二义性

    #include "iostream"
    
    using namespace std;
    
    class Parent_f
    {
    public:
        void show()
        {
            cout<<"This is Parent_f\n";
        }
    };
    class Parent_m
    {
    public:
        void show()
        {
            cout<<"This is Parent_m\n";
        }
    };
    class Son:public Parent_f,public Parent_m
    {
    public:
        void display()
        {
            cout<<"This is son\n";
        }
    };
    int main()
    {
        Son son;
        son.show();
        son.display();
        cout << "Hello world!" << endl;
        return 0;
    }

    上面的代码中,2个父类派生一个子类,但两个父类中都有同名的成员函数。派生出的子类产生二义性问题,编译时会报:

    error: request for member 'show' is ambiguous

        解决方法:

        (1)利用作用域限定符(::),用来限定子类调用的是哪个父类的show()函数

    son.Parent_f::show();
        (2)在类中定义同名成员,覆盖掉父类中的相关成员
    class Son:public Parent_f,public Parent_m
    {
    public:
        void display()
        {
            cout<<"This is son\n";
        }
    
        void show()
        {
            cout<<"show:This is son.\n";
        }
    };


    2.

                                                        

    “菱形”问题——路径二义性

        有最基类A,有A的派生类B、C,又有D同时继承B、C,那么若A中有成员a,那么在派生类B,C中就存在a,又D继承了B,C,那么D中便同时存在B继承A的a和C继承A的a,那么当D的实例调用a的时候就不知道该调用B的a还是C的a,就导致了二义性。

    #include "iostream"
    
    using namespace std;
    
    class Grandpa
    {
    public:
        int year_old;
    };
    
    class Parent_f:public Grandpa {};
    class Parent_m:public Grandpa {};
    
    class Son:public Parent_f,public Parent_m {};
    
    int main()
    {
        Son son;
        son.year_old = 10;
        cout << "Hello world!" << endl;
        return 0;
    }
    

        Grandpa为Parent_f和Parent_m的基类,而Son又继承Parent_f和Parent_m,当Son访问Grandpa的year_old时,会出现二义性错误.

        解决方法:

        (1)使用作用域限定符,指明访问的是哪一个基类的成员。

                注意:不能是Grandpa作用域下限定,因为Son直接基类的基类才是Grandpa,纵使指明了访问Grandpa的成员的话,对于Son来说,还是模糊的,还是具有二义性。

        (2)在类中定义同名成员,覆盖掉父类中的相关成员。

        (3)虚继承、使用虚基类

            教科书上面对C++虚基类的描述玄而又玄,名曰“共享继承”,名曰“各派生类的对象共享基类的的一个拷贝”,其实说白了就是解决多重多级继承造成的二义性问题。父类对祖父类的继承方式改为虚继承,那么子类访问自己从祖父类那里继承过来的成员就不会有二义性问题了,也就是将子类对象里的祖父类对象统一为一个,继承的只有一个祖父类对象,代码如下。

    #include "iostream"
    
    using namespace std;
    
    class Grandpa
    {
    public:
        int year_old;
        void show()
        {
            cout << "year_old:" << year_old <<endl;
        }
    };
    
    class Parent_f:virtual public Grandpa {};
    class Parent_m:virtual public Grandpa {};
    
    class Son:public Parent_f,public Parent_m {};
    
    int main()
    {
        Grandpa grp;
        Parent_f pa_f;
        Parent_m pa_m;
        Son son;
    
        grp.year_old = 100;
        pa_f.year_old = 55;
        pa_m.year_old = 50;
        son.year_old = 10;
    
        grp.show();
        pa_f.show();
        pa_m.show();
        son.show();
        cout << "Hello world!" << endl;
        return 0;
    }

        使用了虚基类的方法,是不是感觉简单方便多了呢








    展开全文
  • 在派生类中对基类成员访问应该是唯一的,但是在多继承时,可能会导致对基类某成员访问出现不一致的情况,这就是C++多继承中的二义性。 有两种继承的情况会产生多义性 一、如果一个派生类从多个基类派生,而这些基类...
  • 一般来说,在派生类中对基类成员的访问应该是唯一的,但是,由于在多继承情况下,可能出现对基类中某个成员的访问不唯一性情况,这称为对基类成员访问的多继承二义性问题 分两种情况: first: 派生类的多个基类中...

    一般来说,在派生类中对基类成员的访问应该是唯一的,但是,由于在多继承情况下,可能出现对基类中某个成员的访问不唯一性情况,这称为对基类成员访问的多继承二义性问题

    分两种情况:
    first: 派生类的多个基类中调用其同名成员时可能出现二义性
    second:派生类有共同基类时访问公共基类成员可能出现二义性

    例子:

    #include <iostream>
    using namespace std;
    
    class A
    {
    	public:
    	A() {cout << "A constructor called" << endl;}
    };
    class B1 : public A
    {
    	public:
    	B1(){cout << "B1 constructor called" << endl;}
    };
    class B2 : public A
    {
    	public:
    	B2(){cout << "B2 constructor called" << endl;}
    };
    class C : public B1, public B2
    {
    	public:
    	C(){cout << "C constructor called" << endl;}
    };
    
    int main(int argc,char **argv)
    {
    	C cc;
    	system("pause");
    	return 0;
    }
    

    在这里插入图片描述
    在实例化C时,调用了两次基类的构造函数;虚基类的引入解决了此类问题
    修改后的代码如下:

    #include <iostream>
    using namespace std;
    
    class A
    {
    	public:
    	A() {cout << "A constructor called" << endl;}
    };
    class B1 : virtual public A
    {
    	public:
    	B1(){cout << "B1 constructor called" << endl;}
    };
    class B2 : virtual public A
    {
    	public:
    	B2(){cout << "B2 constructor called" << endl;}
    };
    class C : public B1, public B2
    {
    	public:
    	C(){cout << "C constructor called" << endl;}
    };
    
    int main(int argc,char **argv)
    {
    	C cc;
    	system("pause");
    	return 0;
    }
    

    在这里插入图片描述
    有调试结果可得,只调用了一次基类A的构造函数

    展开全文
  • C++ 多继承二义性问题 在多重继承中需要解决的主要问题是标识符不唯一即二义性问题比如 当在派生类继承的多个基类中有同名成员时派生类中就会出现标识符不唯一的情况 在多重继承中派生类由多个基类派生时基类之间...
  • 多重继承二义性就是在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——同名二义性 当派生类从个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,...

    什么是二义性?

    • 简单来说就是一个班级有两个同名的人都叫张三, 老师叫张三回答这道题, 这时, 谁都不知道老师指的是哪个张三, 这就是二义
    • 多重继承的二义性就是在继承时,基类之间、或基类与派生类之间发生成员同名时,将出现对成员访问的不确定性——同名二义性
    • 当派生类从多个基类派生,而这些基类又从同一个基类派生,则在访问此共同基类中的成员时,将产生另一种不确定性——路径二义性。

    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;
    }
    
    展开全文
  • 一个派生类可以有两个或多个基类,叫做多继承 1、多继承 class D:public A,public B,public C { public: //类D中新增的成员 }; 2、多继承中构造函数和析构函数 在多继承形式下的构造函数和单继承形式基本相同,就是...
  • 由此c++引入了,多重继承的概念,也就是允许一个派生类指定个基类,这样就被叫做多重继承。 如下代码: #include "stdafx.h" #include <iostream> #pragma warning(disable:4996) #include <string>...
  • 多继承二义性和虚继承(虚基类)

    千次阅读 2017-09-04 16:22:29
    但是,由于在多继承的情况下,可能出现基类中某个成员的访问不唯一的情况,这称为对基类成员访问的二义性。在多继承的情况下,通常有两种可能出现的二义性。 1 派生类的多个基类中调用其同名成员时可能出现二义性...
  • C++多继承二义性

    2013-05-18 15:24:35
    多继承可以看作是单继承的扩展。所谓多继承是指派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承。  多继承下派生类的定义格式如下:  class :,,…  {    };  其中,,,...
  • 多继承- 二义性ambiguous   多个直接父类中 出现同名成员时产生的二义性 同一个父类 通过不同继承路径产生的二义性   例8-6 A1父类中的f1(),还是A2父类中的f1() #include &lt;iostream&gt; ...
  • C++菱形继承如下: #include<iostream> using namespace std; class A { public: int a; }; class B1 : public A { public: int _B1; }; class B2 :public A { public: int _B2; }; class C :public B1, ...
  • C++多继承中二义性的解决方案

    千次阅读 2018-05-27 15:30:24
    出现二义性的原因:派生类在访问基类成员函数时,由于基类存在同名的成员函数,...1. 什么是多重继承二义性 class A{ public: void f(); } class B{ public: void f(); void g(); } class C:public A,pub...
  • 菱形继承问题和虚继承是如何解决二义性与数据冗余的继承是c++的三大特性之一,其中菱形继承问题是一个值得我们学习和掌握的知识点。 1.什么是菱形继承呢? 菱形继承定义为:两个子类继承同一个父类,而又有子类...
  • 一、多重继承二义性问题 举例: #include using namespace std; class BaseA { public: void fun() { cout << A.fun << endl; } }; class BaseB { public: void fun() { cout << B.fun <...
  •  ...多重继承:一个类派生出个类,个类派生出一个类 性质与规则: 1.声明方法:class D:public A,private B,protected C{} 2.调用顺序:先调用A的构造函数,再到B,再到C。虚基类->非虚基
  • 继承中的二义性问题

    千次阅读 2019-03-15 09:42:33
    一、调用不同基类的同名成员时可能出现二义性 class A { public: void setA(int a); int get(); private: int a; } ; class B { public: void setB(int b); int get(); private:...
  • 多重继承二义性以及解决方法

    千次阅读 2016-07-24 16:07:24
    //多重继承二义性以及解决方法 //学习目的:了解类的继承原理及多重继承二义性的解决方法。 /* //本程序代码来源《MFC权威剖析》p68 */ ////////////////////第一种多重继承二义性//////////////// ...
  • 多继承二义性 二义性的产生:1.重名定义 2. 多路径继承 解决二义性的方法: 不重名 — 利用成员名限定法(Bird与Horse中的fun 与 m_weight不重命) 在派生类中定义一个同名成员;(在FlyHorse中也定义fun ...
  • //虚继承的意义//在多继承中,保存共同基类的多份同名成员,虽然有时是必要的,可以在不同的数//据成员中分别存放不同的数据,但在大多数情况下,是我们不希望出现的。因为保留多//份数据成员的拷贝,不仅占有较多的...
  • C++:多继承中的二义性问题

    千次阅读 热门讨论 2014-02-28 20:30:03
    但是,在多继承情况下,可能造成对基类中某个成员的访问出现了不一致的 情况,这时就称对基类成员的访问产生了二义性. 原因之一:  派生类在访问基类成员函数时,由于基类存在同名的成员函数,导致无法确定访问的是...
  • C++ 二义性是什么?怎么解决?

    万次阅读 多人点赞 2018-08-28 09:33:15
    多继承的场景里,当父类中存在同名变量时,子类访问父类的同名变量,将出现二义性,因为编译器不知道你将要访问的是哪个父类中的变量。 举个例子: class A { public: int a; // B1,B2 都将继承一个变量 a };...
  • C++ 继承中的二义性

    千次阅读 2015-02-05 08:53:39
    多重继承的派生类有可能从两个或个基类继承同名成员,对该成员如果不加限定的话,这样使用就是二义性的。即使两个继承的函数有不同的形参表也会产生错误,类似的,即使函数在一个类中是私有的而在另一个类中是公用...
  • 多重继承:一个派生类有两个或个基类,派生类从两个或个基类中继承所需的属性。 多重继承要和多级派生区分,多级派生是指一个类派生出一个子类,这个子类再派生出另一个子类,以此类推。 对于多重继承,c++...
  • 二义性和C++消除二义性

    千次阅读 2020-03-26 17:43:20
    1.二义性 二义性的定义是:“如果文法G中的某个句子存在不只一棵语法树,则称该句子是二义性的。如果文法含有二义性的句子,则称该文法是二义性的。”(该定义来自于百度百科)用通俗的话讲,如果一句话或者一个...
  • 1.赋值兼容规则 (1)派生类对象可以给基类对象赋值,这种情况下派生类对象将从基类继承的成员的值赋值给一个基类对象;但是不允许将一个基类的对象赋值给一个派生类。...2.多继承 (1)一个派生类从两个以上的基类中
  • c/c++ 多重继承下的二义性解决方法

    千次阅读 2014-10-18 16:22:52
     主要用来解决多继承时,可能对同一基类继承继承多次从而产生的二义性。  为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝。  注意:需要在第一次继承时就要将共同的基类设计为虚基类 ...
  • 前天晚上用python写了个多继承代码,写到后面的时候,突然发现实例方法全乱了,经过一个晚上的查删整改,勉强让代码跑了起来(具体...不难看出,菱形继承中也存在数据的二义性,这里的二义性是由于他们间接都有相同...
  • C++多继承

    千次阅读 2019-03-06 10:12:32
    在C++语言中,一个派生类可以从一个基类派生,也可以从...从多个基类派生的继承称为多继承。 1.继承的三种方式 公有继承(public),私有继承(private),保护继承(protected) 三种继承方式的说明,如下表所示: 2...
  • 例如,当在派生类继承个基类中有同名成员时,派生类中就会出现标识不唯一(二义性)的情况,这在程序中是不允许的。如: #include using namespace std; class Base1 { public: int x; int a()

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,086
精华内容 21,234
关键字:

关于多继承二义性