Есть ли способ устранить «окончательную неопределенность переопределения», используя декларацию об использовании? - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь решить проблему страшного бриллианта с помощью методов виртуального класса.

Давайте сначала рассмотрим случай множественного наследования с особенностью конечного виртуального метода. Поскольку существует последний метод, нельзя объявить метод переопределения, но необходимо использовать объявление-использование, чтобы указать, какой метод следует использовать для дочернего класса.

class Mother {
public:
    virtual void foo() final {}
};

class Father {
public:
    virtual void foo() {}
};

class Child: public Mother, public Father {
public:
    // void foo() {Mother::foo();} // This clashes with Mother::foo being final
    using Mother::foo;
};

Приведенный выше код работает, как и ожидалось.

Однако, если мы перейдем к алмазоподобной структуре с абстрактным базовым классом, тот же подход больше не будет работать.

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

class Mother: virtual public GrandParent{
public:
    virtual void foo() override final {};
};

class Father: virtual public GrandParent{
public:
    virtual void foo() override {};
};

class Child: public Mother, public Father {
    using Mother::foo;
};

Компиляция вышеуказанного кода вызовет ошибку: no unique final overrider for ‘virtual void GrandParent::foo()’ in ‘Child’.

Есть идеи, как решить эту проблему?

1 Ответ

0 голосов
/ 18 января 2019

Это язык, который говорит вам, что ваш дизайн неверен.И это.Наследование отражает отношения «есть».Не "has-a".

Решение состоит в том, чтобы использовать композицию вместо наследования.Я бы привел пример, но совершенно неясно, что вы на самом деле намереваетесь выполнить, и не можете придумать ни одного разумного примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...