2016-07-19 1 views
2

Допустим, у меня есть этот простой кодНеоднозначность множественного наследования

#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(); 
} 

это бросает компиляции ошибки времени, потому что вызов функции шоу() является неоднозначным. Я хочу знать, как компилятор это понимает? Создание объекта - это процесс времени выполнения, поэтому, как компилятор знает перед собой, что объект класса C будет создан, который будет вызывать show(). Может ли кто-нибудь сказать мне концепцию, лежащую в основе этого?

+0

Он не должен знать ничего о том, как вы используете класс заранее. Он видит, что вы вызываете 'show()' и не можете выбрать один из двух. – chris

+0

Как он узнает, что объект класса C вызывает show(), если объект еще не создан – alchemist95

+1

Компилятор - это то, что генерирует код для создания объекта. Это действительно то же самое, что объявить строку и сообщить компилятору, что она имеет функцию 'length', но не' foo'. Вы сказали компилятору, что 'obj' является' C'. Вот почему он знает, что это «С». – chris

ответ

2

Вы наследуете оба базовых класса A и B, который имеет тот же метод show в C. Именно по этой причине вы столкнулись с ошибкой компилятора ambiguous access of 'show'.

Чтобы преодолеть это, вам нужно более четко указать, какой метод show вы хотите вызвать. Это было бы легко сделать с помощью оператора разрешения области.

  • Для вызова show метод A: obj.A::show();
  • Для использования метода showB: obj.B::show();
+0

Я получаю это. Не могли бы вы рассказать о том, как это делается? Как компилятор знает, что его объект C, а не объект вызова B show(), если создание объекта является временем выполнения – alchemist95

+0

Не могли бы вы рассказать о том, как это делается? ** Я уже объяснил, как это сделать.** Как компилятор знает, что его объект C, а не объект вызова B show(), если создание объекта - это время выполнения ** Я не уверен, получил ли я ваш вопрос *** – Abhijit

+1

Я думаю, что получаю Это. Компилятор знает, что объект класса C вызывает show(), хотя он не создан. Он делает это, просматривая объявление объекта. Исправьте меня, если я ошибаюсь. – alchemist95

0

Вот ответ, который вы ищете: obj имеет тип C, что означает, что он как тип A, так и тип B. Я стараюсь быть осторожным, чтобы не сказать «has-a», когда оно есть » -a ", но, на мой взгляд, объект типа C также является объектом типа A и типа B. Когда вы вызываете конструктор для типа C, вы также вызываете конструкторы типа A и B. Итак, вплоть до создания объекта, все в порядке. Но после этого компилятор должен решить, какое из двух вызовов show() нужно вызвать. И это когда он запутывается.

2

Эта концепция называется «Поздняя привязка» в «Полиморфизме». Это означает, что код сообщает компилятору понять, что делать во время выполнения. Вы должны использовать виртуальные функции таким образом; и он доступен только в том случае, если вы используете это с помощью «указателей». Позвольте мне привести вам небольшой пример.

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) 
}; 

Если вы создаете Principal объект на основной функции, а затем вызвать его функцию печати(), компилятор будет запустить функцию, которая определена в «Основном» классе. Но если вы не определяете функцию print() в классе, который вы получили из класса «Учитель», тогда, когда вы вызываете функцию print() указателя объекта этого класса, она будет запускать print(), определенную в «Учителе» " класс.

Но опять же не пробуйте это с самим объектом, вы должны сделать это с помощью указателей.

С уважением.