Как избавиться от warning C4250: inherits via dominance?

Уважаемые читатели habrahabr,

помогите мне, пожалуйста, со следующей проблемой.


Пусть у нас есть два интерфейса:
class IA
{
public:
	virtual int FuncA() = 0;
};

class ISuperA : virtual public IA
{
public:
	virtual int FuncSuperA() = 0;
};



Мы делаем какую-то реализацию для каждого из них:
class A1 : virtual public IA
{
public:
	virtual int FuncA() { return 1; }
};

class AIncrement: virtual public ISuperA
{
public:
	virtual int FuncSuperA() { return (FuncA() + 1); }
};



Потом создаем класс, являющегося наследником обоих реализаций интерфейсов:
class A1Increment: virtual public AIncrement, virtual public A1
{
};

int main()
{
	A1Increment a;
	cout << "test: " << a.FuncSuperA() << endl;
}



В этом случае при компиляции в Microsoft Visual Studio 2010 возникает следующий warning:
warning C4250: 'A1Increment': inherits 'A1::A1::FuncA' via dominance



Возникает вопрос: есть ли возможность избавиться от этого warningа?

Если при такой реализации это невозможно, то возможно ли использовать какую-нибудь другую форму наследования\интерфейса?
  • Вопрос задан
  • 4446 просмотров
Пригласить эксперта
Ответы на вопрос 4
@vScherba
Если не желаете подавлять предупреждение, можно явно указать компилятору:
class A1Increment: public AIncrement, public A1
{
    virtual int FuncA()
    {
        return A1::FuncA();
    }
};


Дело в том, что реализацию FuncA можно вызвать 2-мя способами a.AIncrement::FuncA() или a.A1::FuncA(). Вызовы несколько отличаются. 1-ый вызывает AIncrement::ISuperA::IA::FuncA через виртуальную таблицу, а 2-й вызывает непосредственно реализацию A1::FuncA. Компилятор честно (чтобы без неожиданностей) предупредил, что встроен вызов 2-го варианта.

Кстати, для виртуального наследования IA достаточно виртуально унаследовать IA. Ключевое слово virual лишнее в строках:
Ответ написан
Комментировать
Ramires
@Ramires
О предупреждении раз и два. Убрать можно с помощью warning pragma.
GCC и Clang никакого предупреждения не показали.
Ответ написан
@vScherba
class AIncrement: virtual public ISuperA
class A1Increment: virtual public AIncrement, virtual public A1
Ответ написан
Комментировать
@vScherba
Совсем забыл: если у Вас в базовом классе нет членов-данных, то не стоит наследовать его виртуально. Обычное наследование увеличит производительность.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы