Исправлено предупреждение «неиспользуемая функция преобразования» в производном классе

#c #inheritance #multiple-inheritance #compiler-warnings

Вопрос:

Первоначально базовый класс B был производным от класса A. Но поскольку C происходит как от A, так и от B, я получил неприятное наследование в форме ромба и, таким образом, удалил наследование в B, выбрав функцию преобразования в A.

Теперь я получаю предупреждения для классов типа C из-за того, что преобразование в базовые классы никогда не используется. Как я могу их исправить или удалить? Программа работает без проблем.

 // base class providing most functionality
class A{
public:
int doStuff(){ return 0; };
};

// pure virtual interface providing a conversion to A
class B{
public:
virtual operator Aamp;()=0;
};

// interface implementation
class C: public A, public B{
public:
virtual operator Aamp;() override{return *this;}
};
 

предупреждение: функция преобразования, преобразующая «C» в его базовый класс «A», никогда не будет использоваться

         virtual operator Aamp;() override{return *this;}
                ^
 

Комментарии:

1. А как насчет виртуального наследования вместо этого? Если и B то, и другое и C фактически унаследуется от A вас, в итоге получится один A экземпляр C sinlgle …

2. C c; Aamp; a = c; не будет использовать ваш operator Aamp; ; возможно, возможно использование других имен.

3.Может быть, еще проще: есть ли какая-то причина B , по которой не следует публично наследовать от A ? Если нет, просто сделайте это, и если C затем он публично наследует от B , он A автоматически получает наследование, так почему же тогда он должен явно наследовать от A снова?

4. Потому что мой случай немного сложнее, когда C наследует не от A, а класс, производный от A вместо этого. Все различные классы типа C наследуются от другого класса, производного от A. Интерфейс B используется только в терминах методов, предоставляемых A.

5. Что ж, тогда вам следовало бы описать свою проблему как таковую: D наследование от B и C откуда оба последних наследуют A . Но опять же: пусть B и C то, и другое фактически наследуется от A вас, и вы в безопасности: D получает один экземпляр A . Или это тот случай, когда вы не можете изменить C (как, очевидно, могли B бы )?

Ответ №1:

Учитывая экземпляр C , ваш компилятор вполне способен преобразовать его в ссылку на A , не нуждаясь в этой функции преобразования. Будет использоваться неявное преобразование, и эта перегрузка оператора никогда не будет использоваться, это буквально то, что говорит диагностика компилятора.

Если ваша цель здесь состоит в том, чтобы B методы получили ссылку на связанный A объект, то простое решение состоит в том, чтобы использовать для этого обычную функцию вместо перегруженного оператора:

 class B{
public:
virtual Aamp; get_a()=0;
};

// interface implementation
class C: public A, public B{
public:
virtual Aamp; get_a() override{return *this;}
};
 

Другие методы B просто нужно будет использовать get_a() явно. Но, если вы так желаете:

 class B{
public:
virtual Aamp; get_a()=0;
operator Aamp;() { return get_a(); }
};