Реализация чисто виртуальных функций с множественным наследованием

Предположим, есть этот интерфейс:

class A{
public:
virtual foo()=0;
};

И класс B который реализует этот интерфейс:

class B:public A{
public:
virtual foo(){} //Foo implemented by B
}

Наконец, класс C который имеет классы A а также B в качестве базовых классов:

Class C : public A, public B {
};

Мой вопрос, есть способ сказать компилятору, что реализация для foo тот из класса B без явного вызова B::foo()?

5

Решение

Как отметил @BenVoigt в комментариях, приведенный ниже ответ работает только из-за ошибки в g ++ (что означает, что он не гарантированно продолжит работать, и он определенно не переносим). Таким образом, хотя он может делать то, что вы хотите, если вы используете определенный (глючный) компилятор, это не вариант, который вы должны использовать.

Делать использование виртуальное наследство хоть.


Это не совсем тот сценарий, что код в вопросе подразумевается, но предложение

Мой вопрос, есть способ сказать компилятору, что
Реализация для Foo из класса B, не делая
явный вызов B :: foo ()?

кажется, что запрашивает синтаксис для различения нескольких базовых версий функции без использования :: Классификатор.

Вы можете сделать это с using директива:

#include <iostream>
class A {
public:
A(){}
virtual void foo(){std::cout<<"A func";}
};

class B: virtual public A {
public:
B(){}
virtual void foo(){std::cout<<"B func";}
};
class C:virtual public A, virtual public B {
public:
C(){}
using A::foo; // tells the compiler which version to use
// could also say using B::foo, though this is unnecessary
};

int main() {
C c;
c.foo(); // prints "A func"return 0;
}

Конечно, сам код в вопросе не требует этого вообще, как указывали другие ответы.

3

Другие решения

Просто используйте виртуальное наследование, чтобы A подобъект предоставлен B это тот же объект, используемый в C,

Или пиши class C : public B… это будет неявно использоваться как A во всяком случае, через базовый класс B,


До того, как вопрос был отредактирован:

B::foo не совместим с A::foo,

Требуемая подпись

ReturnType /* missing from question */ foo(A* const this /* this parameter is implicit */);

Но B::foo имеет подпись

ReturnType foo(B* const this);

A*, который будет передан в виртуальную функцию, не является B*, чего требует реализация. Если B унаследованный от Aто компилятор сгенерирует B::foo принять A* const subobject и найти B* const this объект из этого указателя подобъекта. Но B::foo не знает об отношениях в C,

2

Поскольку в вашем примере есть два базовых класса (которые могут быть проблемой дизайна / запахом дизайна, я бы рассмотрел это), вам придется явно вызывать реализацию, к которой вы стремитесь, будь то A::foo() или же B:foo(),

Если все, что B делает, это обеспечивает реализацию foo() Я бы посоветовал переместить реализацию в A (вы можете предоставить реализацию для чисто виртуальной функции), но даже в этом случае вам придется вызывать ее через ее полное имя.

0
По вопросам рекламы [email protected]