class Base
{
....
private:
virtual void _print() = 0;
}
Это означает: вы можете переопределить _print
, но не можете его назвать, только Base
имеет право вызывать его.
Сейчас:
class Base
{
public:
void print()
{
_printFunc();
}
делает это, вызывает _printFunc
как виртуальную функцию, которая соответствует текущей реализации объекта.Он не измеряет, как был вызван print()
.
Добавление Subclass1::
в качестве префикса просто меняет область имен и не влияет на поведение метода.Это оказывает влияние только на область имен.
Теперь, если виртуальный метод имеет такой префикс, то выбор области действия имени указывает компилятору, что вам следует отказаться от абстракции, и вам нужно вызвать определенный метод.В этом случае метод вызывается без обращения к виртуальной таблице.
Двойное наследование не влияет на эту проблему.
Вы можете предоставить вспомогательный метод, который вы сможете вызывать от предка:
class Subclass1 : public Base
{
....
protected:
void sub1_print() // not virtual
{
std::cout << "Subclass1\n";
}
private:
void _print() /*override*/
{
sub1_print();
}
};
class Subclass2 : public Base, public Subclass1
{
....
private:
void _print() /*override*/
{
sub1_print();
std::cout << "Subclass2\n";
}
};