简体   繁体   English

多重继承中的歧义

[英]Ambiguity in Multiple Inheritance

Let's say i have this simple code 假设我有这个简单的代码

#include <iostream>
using namespace std;

class A {
 public:
    void show() {
        cout << "A" << endl;
    }
};

class B {
 public:
    void show() {
        cout << "B" << endl;
    }
};

class C:public A, public B {
};

int main()
{
    C obj;
    obj.show();
}

this throws a compile time error because the call to function show() is ambiguous. 由于对函数show()的调用不明确,因此会引发编译时错误。 I want to know how does the compiler understand this? 我想知道编译器如何理解这一点? Object creation is a run time process, so, how does the compiler know before hand that an object of Class C is going to be created which would invoke show(). 对象创建是一个运行时过程,因此,编译器如何事先知道将要创建将调用show()的C类对象。 Can anybody please tell me the concept behind this? 有人可以告诉我这背后的概念吗?

You are inheriting both the base classes A and B which has the same method show in C . 您将同时继承基类AB ,它们具有在C show的相同方法。 This is the reason you are facing the compiler error ambiguous access of 'show' . 这就是您面对ambiguous access of 'show'的编译器错误ambiguous access of 'show'的原因。

To get over it, you need to be more explicit on which `show method you would want to invoke. 为了克服它,您需要更明确地说明要调用哪种show方法。 It would be easy to do it using the scope resolution operator. 使用范围解析运算符很容易做到。

  • To invoke show method of A : obj.A::show() ; 调用A show方法: obj.A::show() ;
  • To invoke show method of B : obj.B::show() ; 调用B show方法: obj.B::show() ;

This concept is called "Late Binding" in "Polymorphism". 这个概念在“多态性”中称为“后期绑定”。 It means, the code tells the compiler to understand what to do on runtime. 这意味着,代码告诉编译器了解在运行时该做什么。 You should use virtual functions in this manner; 您应该以这种方式使用虚函数。 and it is only available when you use this with "pointers". 并且仅当与“指针”一起使用时才可用。 Let me give you a little example. 让我举一个例子。

class Teacher {                          //base class
    string name;
    int numOfStudents;
public:
    Teacher( const string &, int );      // constructor of base
    virtual void print() const;          // a virtual (polymorphic) function
};
class Principal : public Teacher{        // derived class
    string SchoolName;
public:
    Principal( const string &, int , const string & );
    void print() const;                  // also virtual (polymorphic)
};

If you create a Principal object on main function and then call its print() function, compiler will run the function which is defined in "Principal" class. 如果在主函数上创建Principal对象,然后调用其print()函数,则编译器将运行在“ Principal”类中定义的函数。 But if you don't define a print() function in a class which you derived from "Teacher" class, then when you call a print() function of that class' object pointer it will run the print() defined in "Teacher" class. 但是,如果您没有在从“ Teacher”类派生的类中定义print()函数,则当您调用该类的对象指针的print()函数时,它将运行在“ Teacher”中定义的print() ”类。

But again do not try this with the object itself, you should do it with pointers. 但同样不要对对象本身尝试此操作,而应使用指针进行操作。

Best regards. 最好的祝福。

Here is the answer you are looking for: obj is of type C which means it is both type A and type B. I am trying to be careful not to say "has-a" when it is "is-a", but, in my mind, an object of type C has also an object of type A and type B. When you call a constructor for type C, you would also call the constructors of type A and B. So, up to the point of creation of obj, everything is fine. 这是您要寻找的答案:obj的类型为C,这意味着它既是类型A,又是类型B。我试图小心不要在它是“ is-a”时说“ has-a”,但是,在我看来,类型C的对象也具有类型A的对象和类型B的对象。当您为类型C调用构造函数时,也会调用类型A和B的构造函数。因此,直到创建对象为止obj,一切都很好。 But, after that the compiler has to decide which of the two show()'s to call. 但是,此后,编译器必须决定要调用两个show()中的哪一个。 And that is when it is getting confused. 那就是当它变得混乱时。

You are inheriting from both the classes A and B. That's why it is showing you an error, namely because it is ambiguous. 您同时从类A和类B继承。这就是为什么它向您显示错误,即因为它是模棱两可的。 To handle this you can refer explicitly to the function or method should be invoked at the time of calling by the object of the C's object. 要处理此问题,您可以显式引用在C的对象的调用对象时应调用的函数或方法。 This way the compiler doesn't get confused and doesn't show any error to you. 这样,编译器不会感到困惑,也不会向您显示任何错误。 CODE : 代码:

class A{
   public: 
     void show(){ cout<<"Class A"; }
};
class B{
   public:
      void show(){  cout<<"Class B";  }
};
class C : public A , public B{
   public:
      void disp(){  A::show(); } // Here You can make explicit from which class the method
                               //  shall be called. I refer to method "show" from class A.
}
main(){
  C obj;
  obj.disp(); // Ambiguity in Multiple Inheritance Problem Solved

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM