Подтвердить что ты не робот

Наследование по господству - это действительно плохо?

Я один из тех людей, которым приходится компилировать свой код с 0 предупреждениями. Обычно я уважаю компилятор, и если он выдает мне предупреждение, я воспринимаю его как знак того, что немного поправлю свой код. Если я должен сказать компилятору игнорировать данное предупреждение, я немного дергаюсь.

Но этого я не могу обойти, и из того, что я могу сказать, я ничего не сделал "плохо". Кто-нибудь думает, что это плохой дизайн? Я не вижу ничего особенно неприятного в этом отношении (кроме "злого алмаза" ), но это совершенно правильный и полезный код. Но он генерирует (в MSVC) предупреждение уровня 2!

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

class Bar : public virtual IFoo
{
public:
    virtual void foo() { std::cout << "Hello, world!"; }
};

class Baz : public virtual IFoo
{

};

class Quux : public Bar, public Baz
{

};

Теперь, если я создам объект Quux, следует ожидать выполнения Bar:: foo. MSVC очень полезен: он предупреждает меня, что он недостаточно двусмысленен?

предупреждение C4250: "Quux": наследует "Bar:: Bar:: foo" через доминирование

Теперь я узнаю, что могу отключить это предупреждение с помощью прагмы, но это не вопрос, который я задаю здесь. Есть ли причина, по которой я должен слушать компилятор здесь, или это просто чрезмерно резкое предупреждение?

4b9b3361

Ответ 1

При выполнении виртуального наследования плохая идея не явно переопределять каждый член в самом производном классе. Кроме того, вы просите, чтобы ваш код умер от ужасной смерти, когда кто-то меняет один из ваших базовых классов, который наследуется от виртуальной базы. Там нет ничего плохого в этом, ваша программа не будет терпеть крах или все так же, но это неплохая идея обслуживания. Если вы хотите вызвать версию Bar::foo, вам следует просто делегировать ее в Quux::foo.

Ответ 2

Что касается работоспособности вашего кода, просто напомните вам, что Bar является доминирующей реализацией foo. Вам просто нужно сообщить, что это не предупреждение, так что если вы отлаживаете и думаете, что вы не вытаскиваете свои волосы:).

Ответ 3

Есть ли причина, по которой вы не пишете:

class Quux : public Bar, public Baz
{
    using Bar::foo;
};

?

Это дает вам тот же уровень повторного использования, без хрупкости.