О множественном наследовании и определении виртуальной функции
У меня есть сценарий множественного наследования без виртуальных базовых классов:
Ta Tb
| |
B C
\ /
A
Ta и Tb - это два разных класса шаблонов, которые объявляют виртуальную функцию с именем f(). Я хочу переопределить две функции в области A, потому что мне приходится взаимодействовать с данными B и C в этих методах. Но я не знаю, как это сделать.
class Tb {
protected:
virtual void f() {};
public:
void call() {
this->f();
};
};
class Tc {
protected:
virtual void f() {};
public:
void call() {
this->f();
};
};
class B : public Tb {
public:
void doSomething() {};
};
class C : public Tc {
private:
int c;
public:
void inc() { c++; };
};
class A : public B, public C {
protected:
void f() { // this is legal but I don't want to override both with the same definition.
// code here
}
// if Tb::f() is called then i want to call C::inc()
// if Tc::f() is called then i want to call B::doSomething()
public:
void call() {
B::call();
C::call();
};
};
Есть ли синтаксис для переопределения обоих методов с разными определениями или я должен определить их в B и C?
Спасибо
Изменить:
Моя проблема заключается не в том, что вызов can not Tb:: f() или Tc:: f(), но я хочу определить два разных поведения, если вызывается Tb:: f() или Tc:: f(). Эти методы называются самими Tb и Tc в собственных публичных методах.
Модифицированный пример, поэтому, возможно, более ясно, что я хочу сделать...
Ответы
Ответ 1
Есть ли синтаксис для переопределения обоих методов с разными определениями или я должен определить их в B и C?
Короткий ответ: нет.
Ваш A:f()
будет отменять как Ta::f()
, так и Tb::f()
.
Если вам нужны разные переопределения, единственным решением является вставка вспомогательных классов Hb и Hc:
Ta Tb
| |
B C
| |
Hb Hc
\ /
A
Hb
может быть как две функции, просто переименовать функцию:
class Hb: public B {
protected: // overrides from Ta
virtual void f() { Ta_f(); }
protected: // new virtuals
virtual void Ta_f() = 0;
};
а затем вы можете определить A::Ta_f()
для выполнения всех необходимых действий (включая вызов B::f()
!)
Ответ 2
Вы переопределили оба класса A
. Если бы вы этого не сделали, была бы двусмысленность, если директива using
не используется, чтобы явно указать, какой метод вы предпочитаете.
Вы можете переопределить эти методы отдельно в классах B
и C
, но опять же, как только класс A
наследует и вы должны решить, какой из них следует использовать.
Ответ 3
Вы абсолютно должны иметь возможность заменить A
на Tb
или Tc
? Если нет, рассмотрели ли вы использование композиции в A
вместо наследования?
Если вам нужно подставить таким образом, рассмотрите ли вы простой способ и просто назовите родительские методы двумя разными именами? Поскольку вы хотите переопределить их отдельно, указание состоит в том, что они не делают то же самое.