0

Рассмотрим следующий простой пример:Как в C++ множественное наследование выбрать, какой метод базового класса будет унаследован?

#include <iostream> 
using namespace std; 

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

class B: public virtual A { 
public: 
    virtual void foo(){ 
     cout<<"B"<<endl; 
    } 
}; 

class C : public virtual A { 
public: 
    virtual void foo(){ 
     cout<<"C"<<endl; 
    } 
}; 

class D : public B, public C { 
    public: 
     void print(){ 
      foo(); 
     } 
}; 

int main() { 
    D d; 
    d.print(); 
    return 0; 
} 

Этот код не будет работать, так как вызов Foo Неоднозначный. Но вопрос в следующем:

Как определить, какие методы должны быть унаследованы? И если у меня есть такая возможность?

+4

В принципе есть один вопрос и один advice: В: Каков ваш конкретный прецедент для множественной наследования двусмысленности? A: Не используйте множественное наследование, так как почти всегда существует путь, ведущий к более явным проектам. – MABVT

+0

@MABVT Множественное наследование чрезвычайно полезно, и альтернативы обычно добавляют сложность. – curiousguy

+0

@curiousguy Хм. Множественное наследование может быть полезно, если вам не нужно иметь дело с этими проблемами двусмысленности! На самом деле у меня редко были случаи использования для Mult.Inh. с сознательной двусмысленностью, которая была задействована до ... Oo Просто быть любопытным: есть ли у вас какие-то конкретные примеры, где ситуация с OPs возникает и на самом деле находится в полезном контексте? Кажется, я могу узнать что-то новое на данный момент. ;) – MABVT

ответ

1

Disambigate call to the function. Рассмотрим следующий пример:

class A { virtual void foo(); }; 
class B { virtual void foo(); }; 
class C : public A ,public B { void foo(); }; 

Для вызова либо Foo из A, B или даже из дочернего класса: C сделать

C *obj = new C; 
obj->foo(); 
obj->A::foo(); 
obj->B::foo(); 

Источник/вдохновение: http://www.cprogramming.com/tutorial/multiple_inheritance.html

+0

Итак, вы предлагаете мне часто писать функцию foo в C-классе, где вызывать вызовы на этот вариант foo, который мне нужен? –

+0

Да, вам нужно переопределить foo() в классе C, но это не обязательно нужно делать. Его использование заключается в том, чтобы сделать явную квалификацию. Tldr, C :: foo() может быть пустым. – Propolys

+0

Если это может быть пустым, почему бы назвать эту функцию? – curiousguy