Я задал этот вопрос:
Лучший способ реорганизовать иерархию классов
так плохо, что я был вынужден принять совершенно правильный ответ. Моя проблема заключается в следующем:
У меня есть класс CGrandMother
публичный метод virtual bool Compute()
это делает
virtual bool Compute()
{
return false;
}
От CGrandMother
получает публично CMother
который не реализует Compute
, Теперь из CMother
выводить публично C1
а также C2
которые реализуют virtual bool Compute()
, Сейчас virtual bool C1::Compute()
а также virtual bool C2::Compute()
соответственно делать много вещей, соответствующих соответственно C1
и к C2
, но также много идентичных вещей, соответствующих CMother
, Теперь есть класс CFamily
имеющий в качестве члена указатель на CMother
и почти везде в коде Compute
вызывается через строки вида
ptrCMother->Compute();
Я хочу выделить общие вещи, связанные с CMother
Завершен в C1
а также C2
чтобы мне не пришлось менять все эти ptrCMother->Compute();
, Конечно, я могу создать функцию-член в CMother
делать это, и позвонить последнему в bool C1::Compute()
а также bool C2::Compute()
, Но…
В c++
, если у вас есть B
вытекающий из A
, A::dostuff()
а также B::dostuff()
и если p
указывает на тип B
затем p->dostuff()
выполнит B::dostuff()
по полиморфизму. Я хотел бы знать, есть ли идиома / шаблон, позволяющий мне достичь этого: «p->dostuff()
«выполнит»A::dostuff()
«или нет (в соответствии с bool
скажем) а потомB::dostuff()
«, что, конечно, не происходит в c++
для функций-членов класса, которые не являются конструкторами и т. д.
Для ясности: базовый метод не вызывается до того, как его соответствующий производный метод будет вызван косвенным путем. Существует ли идиома / шаблон, позволяющий вызывать базовый метод (или нет, согласно bool
) до его соответствующего производного метода?
Что не так с упомянутым вами решением, состоящим в создании метода в классе CMother, который вызывается его дочерними элементами?
#include <iostream>
#include <memory>
using namespace std;
class CGrandMother
{
private:
virtual bool _Compute()
{
return false;
}
public:
bool Compute()
{
return _Compute();
}
};
class CMother : public CGrandMother
{
protected:
void _CommonStuff()
{
cout << "work common to children" << endl;
}
};
class C1 : public CMother
{
private:
virtual bool _Compute() override
{
_CommonStuff();
cout << "work specific to C1" << endl;
return true;
}
};
class C2 : public CMother
{
private:
virtual bool _Compute() override
{
_CommonStuff();
cout << "work specific to C2" << endl;
return true;
}
};
int main() {
unique_ptr<CMother> c1(new C1);
unique_ptr<CMother> c2(new C2);
c1->Compute();
c2->Compute();
return 0;
}
Обратите внимание, что я ограничил модификаторы доступа моих классов:
Кроме того, вы заставляете CMother публично наследовать от CGrandMother, что означает, что CMother является CGrandMother. Это действительно так?
Также обратите внимание, что если CMother был главой иерархии, то вы могли бы вызвать _CommonStuff () через его открытый (но не виртуальный!) Метод Compute, и все подклассы также автоматически вызовут _CommonStuff (). Это одна из замечательных особенностей этого шаблона: вы можете легко заставить свой метод Compute () работать, который является общим для всех подклассов, проверять инварианты и т. Д.
Это будет выглядеть так: https://ideone.com/vXd4fL
Я удалил CGrandMother, и теперь CMother является главой моей иерархии. В своем открытом методе Compute () я вызываю _CommonStuff (). Детям нужно только реализовать _Compute (). _CommonStuff () будет вызываться автоматически всеми дочерними элементами, когда они вызывают Compute ().
Других решений пока нет …