精华内容
下载资源
问答
  • 一丶二义性问题在派生类中对基类成员的访问应该是唯一的,但是在多继承中这种访问可能不唯一,这是就会产生对基类成员访问的二义性二义性有以下两种情况: 1)派生类继承自两个基类,两个基类中具有相同的成员...

    一丶二义性问题

    在派生类中对基类成员的访问应该是唯一的,但是在多继承中这种访问可能不唯一,这是就会产生对基类成员访问的二义性。
    二义性有以下两种情况:
    1)派生类继承自两个基类,两个基类中具有相同的成员

    class base1
    {
    public:
        void fun();
    };
    class base2
    {
    public:
        void fun();
    }
    class derived:public base1,base2{};
    
    int main()
    {
        derived obj;
        obj.fun();//产生二义性,两个基类中都有fun()函数
        return 0;
    }
    

    解决办法:
    方法一:

    <对象名>.<基类名>::<函数名>(参数表)
    obj.base1::fun();

    方法二:在派生类中定义同名函数

    class derived
    {
    public:
        void fun(){base1::fun();}
    };

    2)派生类继承自多个基类,这些基类又继承自同一个基类

    class Base
    {
    public:
        int data;
    };
    class Derived11:public Base{};
    class Derived12:public Base{};
    class Derived2:public Derive11,public Derived12{};
    int main()
    {
        Derived obj;
        obj.data=1;//产生二义性
        return 0;
    }

    解决办法:

    obj.Derived11::data;

    二丶虚基类

    当一个派生类从多个基类派生,而这些基类又有一个共同基类,当对该基类中说明的成员进行访问时,就会产生上面所说的那种二义性,因此虚基类就是为了解决这种问题。

    关键点:
    虚基类是使这个公共基类在派生类中只产生一个对象即可~

    格式如下:

    class <类型>:virtual<继承方式><基类名>

    上面程序改写成虚基类后:

    class Base
    {
    public:
        int data;
    };
    class Derived11:virtual public Base{};
    class Derived12:virtual public Base{};
    class Derived2:public Derived11,public Derived12{};
    
    //这个时候再访问data就只指向Base中的data
    Derived2 obj;
    obj.data=2;//无二义性问题,因为data就只代表Base.data,也就是上面说的虚基类是使这个公共基类在派生类中只产生一个对象即可~
    展开全文
  • c++多继承二义性的另类解决办法

    千次阅读 2010-05-11 12:11:00
    多继承可以看作是单继承的扩展。所谓多继承是指派生类具有个基类,派生类与每个基类之间的关系仍可看作是一个单继承。 多继承下派生类的定义格式如下: class :,,… { }; 其中,,,…是三种继承方式:public、...

    多继承可以看作是单继承的扩展。所谓多继承是指派生类具有多个基类,派生类与每个基类之间的关系仍可看作是一个单继承。

        多继承下派生类的定义格式如下:

        class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…

        {

        <派生类类体>

        };

        其中,<继承方式1>,<继承方式2>,…是三种继承方式:public、private、protected之一。例如:

        class Base

        {

        …foo(){};

        };

       class A

        {

        …foo(){};

      …AWant(){};

        };

        class B

        {

        …foo(){};

        …BWant(){};

        };

        class C : public A, public B

        {

        …foo(){};

        …BWant(){};

        …AWant(){};

        };

     

    但是当class A:public class Base;

    class B:public class Base;

    时,即两个基类A,B又派生于Base基类的时候,就可能出现二义性。

    C在调用同名方法foo时,无法知道是调用A的foo方法还是B的foo方法。从而出现二义性.

     

    由于我只想我通过将C的实例指针赋值给B类指针,从而只暴露BWant方法。

    我的的一种另类解决方法是:

    改写B类:

        class B :public Base

        {

         B(C* c):_c(c){};

        …foo(){};

        …BWant(){ c->BWant();};  //间接调用C类的BWant()方法。

        protected:

        C* _c;

        };

    改写C类,只继承A基类

        class C : public A

        {

        …foo(){};

        …BWant(){};

        …AWant(){};

        };

       C* c=new C();

        B* b = new B(c);// 将C实例作为参数传入B类构造函数

        b->BWant();      // 封装,间接调用C类的BWant()方法。

       

    展开全文
  • 主要介绍了C++多重继承二义性原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • C++多继承二义性

    2019-06-30 14:04:11
    在派生类中对基类成员访问应该是唯一的,但是在多继承时,可能会导致对基类某成员访问出现不一致的情况,这就是C++多继承中的二义性。 出现二义性主要有以下两种情况 情况一: 如果一个派生类从个基类派生,...

    导言

           在派生类中对基类成员访问应该是唯一的,但是在多继承时,可能会导致对基类某成员访问出现不一致的情况,这就是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, public B2{
    public:
    	int c1;
    };
    
    int main(){
    	C  c1;
    	c1.b1 = 100;
    	c1.b2 = 200;
    	c1.c1 = 300;
    
    	c1.a = 500; //继承的二义性 和 虚继承解决方案
    
    	cout << "end..." << endl;
    	system("pause");
    	return 0;
    }

    编译时提示:

    我们可以看到,编译器说a是模糊不清。

    那么通过什么方法可以解决呢,答案是虚继承,即在B1和B2继承A时加上virtual关键字即可,如下所示:

    
    #include <iostream>
    using namespace std;
    
    class A{
    public:
    	int a;
    };
    
    class B1 : virtual public A{
    public:
    	int b1;
    };
    
    class B2 : virtual public A{
    public:
    	int b2;
    };
    
    class C : public B1, public B2{
    public:
    	int c1;
    };
    
    int main(){
    	C  c1;
    	c1.b1 = 100;
    	c1.b2 = 200;
    	c1.c1 = 300;
    
    	c1.a = 500; //继承的二义性 和 虚继承解决方案
    
    	cout << "end..." << endl;
    	system("pause");
    	return 0;
    }

    情况一有以下问题:

    1. 那么问题来了,B1和B2加virtual关键字与否他们的类大小是否相等,答案是不相等的,继承时加了virtual关键字类的空间会大四个字节,也就是会加入一些特性来解决C++多继承的二义性。

    2. B1和B2没有共同的基类,但是他们有同名的成员,而C继承了B1和B2同时加入virtual关键字能否解决多继承二义性问题?测试发现是不能解决的,详见以下“情况二”。

    情况二:

           派生类在访问基类成员时,由于基类存在同名的成员,基类不知道是方法谁

    #include<iostream>
    using namespace std;
    
    
    class Base1 {
    public:
    	void fun() {
    		cout << "I am base-1 " << endl;
    	};
    };
    
    class Base2
    {
    public:
    	void fun() {
    		cout << "I am base-2 " << endl;
    	};
    };
    
    class Subclass : public Base1, public Base2 {
    public:
    	void print() {
    	}
    };
    
    int main() {
    	Subclass obj;
    	obj.fun();   //产生二歧义
    	system("pause");
    	return 0;
    }

    同样产生二义性结果:

    这个问题可以在访问基类成员时使用作用域运算符来解决,即obj.Base1::fun()方式,如上例写成:

    obj.Base1::fun();

    展开全文
  • 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++引入了,多重继承的概念,也就是允许一个派生类指定个基类,这样就被叫做多重继承。 如下代码: #include "stdafx.h" #include <iostream> #pragma warning(disable:4996) #include <string>...
  • 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...
  • 多继承二义性 二义性的产生:1.重名定义 2. 路径继承 解决二义性的方法: 不重名 — 利用成员名限定法(Bird与Horse中的fun 与 m_weight不重命) 在派生类中定义一个同名成员;(在FlyHorse中也定义fun ...
  • 问题:C++菱形继承产生二义性产生的原因(解决方法及简单案例) 本程序通过VC++ 6.0编译与测试,R为A,B的父类,A,B为C的父类,具体代码如下: 菱形继承的示意图: //菱形继承产生的二义性 #include &lt;...
  • C++ 继承中的二义性

    千次阅读 2015-02-05 08:53:39
    多重继承的派生类有可能从两个或个基类继承同名成员,对该成员如果不加限定的话,这样使用就是二义性的。即使两个继承的函数有不同的形参表也会产生错误,类似的,即使函数在一个类中是私有的而在另一个类中是公用...
  • 一个派生类可以有两个或个基类,叫做多继承 1、多继承 class D:public A,public B,public C { public: //类D中新增的成员 }; 2、多继承中构造函数和析构函数 在多继承形式下的构造函数和单继承形式基本相同,就是...
  • 转载C++多继承中的二义性问题 在派生类中对基类成员的访问应该是唯一的.但是,在多继承情况下,可能造成对基类中某个成员的访问出现了不一致的情况,这时就称对基类成员的访问产生了二义性. 原因一、 派生类在访问...
  • 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++菱形继承二义性问题 1.菱形继承(路径二义性问题) 在实现继承的过程中,若派生类B,C同时继承基类A,派生类D同时继承类B,C这样对于基类A中的成员相当于在D被继承过两次,A,B,C,D整体关系构建成为一个...
  • C++多重继承二义性避免

    千次阅读 2016-05-14 17:34:24
    1. 什么是多重继承二义性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class A{ public:  void f(); }   class B{ public:  void f();  void g(); }   ...
  • c1对象不能访问变量b,这就是多继承中的二义性 解决方法:添加virtual关键字(虚继承)。 #include using namespace std; class B { public: int b; private: }; class B1 : virtual public B { ...
  • C++多继承中的二义性问题

    千次阅读 热门讨论 2014-02-28 20:30:03
    情况,这时就称对基类成员的访问产生了二义性. 原因之一:  派生类在访问基类成员函数时,由于基类存在同名的成员函数,导致无法确定访问的是哪个基类的成员函数,因此出现了二义性错误。 例如: #include using...
  • C++多继承中二义性问题--虚基类

    千次阅读 2005-04-27 15:58:00
    #include class Base{ public: Base() { std::cout } ~Base() { std::cout } vo
  • C++继承防止二义性

    千次阅读 2009-04-20 23:05:00
    本文发表在:http://patmusing.blog.163.com/blog/static/135834960201032527733/
  • C++虚拟继承解决菱形继承二义性

    千次阅读 2012-10-29 15:36:03
    在过去的学习中,我们始终接触的单个类的继承,但是在现实生活中,一些新事物往往会拥有两个或者两个以上事物的属性,为了解决这个问题,C++引入了多重继承的概念,C++允许为一个派生类指定个基类,这样的继承结构...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,159
精华内容 8,863
关键字:

c++多继承二义性

c++ 订阅