Множественный порядок наследования используется в разрешении функции?

Был опубликован вопрос о классах интерфейса наследования и смешивания:
Множественное наследование интерфейсов в C ++
Что привело меня к этому вопросу: Влияет ли порядок наследования на правила разрешения функций?

Дано:

struct Binary_Stream_Read_Intf
{
virtual void load_from_buffer(uint8_t*& buffer_ptr) = 0;
};

struct Binary_Stream_Write_Intf
{
virtual void store_to_buffer(uint8_t*& buffer_ptr) const = 0;
};

struct Binary_Stream_Read_Write_Intf
: public Binary_Stream_Read_Intf,
public Binary_Stream_Write_Intf
{ ; };

struct Binary_Stream_Write_Read_Intf
: public Binary_Stream_Write_Intf,
public Binary_Stream_Read_Intf
{ ; };

Вот мои вопросы:

  1. Являются Binary_Stream_Read_Write_Intf а также
    Binary_Stream_Write_Read_Intf тот же самый?
  2. Можно ли заменить одно на другое в вызовах функций?
  3. Могут ли они оба использоваться для функции, требующей
    Binary_Stream_Read_Intf?

1

Решение

1 Нет, они не одинаковы. Вы объявили две разные структуры с двумя разными именами. Компилятор будет относиться к ним как к совершенно другому. Это похоже на высказывание

class Newspaper
{
int volume;
};
class TelevisionAudioControl
{
int volume;
};

Это два одинаковых? Тот факт, что они имеют одинаковые члены, недостаточен для того, чтобы компилятор считал их одинаковыми. Но, в моем примере, поскольку они совместно используют одни и те же члены, вы можете избежать использования явного приведения адреса одного к другому:

TelevisionAudioControl tac;
Newspaper * n = (Newspaper *)&tac;

а также n->volume все еще будет работать. Это больше связано с магией и опасностью указателей, чем с чем-либо еще, и зависит от поведения компилятора, так же как и от технически неопределенного поведения. И если он работает вообще, он работает только тогда, когда все члены одинаковы и в том же порядке. Я не уверен, что в вашем примере функции будут в одном и том же порядке, поэтому я не могу гарантировать, что вы могли бы сделать это плохое колдовство. Поскольку функции являются виртуальными, вы, вероятно, просматриваете таблицы указателей виртуальных функций и будете в порядке.

2 Если функция вызывает Binary_Stream_Read_Write_Intf или Binary_Stream_Write_Read_Intf, то нет. Компилятор принимает только этот класс или что-либо унаследованное от него, и ни один класс не является потомком другого. (Однако вы можете сказать, что они братья и сестры.) Однако, если функция вызывала либо Binary_Stream_Write_Intf, либо Binary_Stream_Read_Intf, то вы можете, так как это вызывает родителя, который у них обоих общий. Как обычно, если нет общего наследования, вы не можете заменить. Если функция вызывает общий суперкласс, да, любой из них будет работать.

3 Они оба наследуются от Binary_Stream_Read_Intf, так что да.

2

Другие решения

  1. Нет, просто как struct Foo {}; а также struct Bar {}; не то же самое.

  2. Нет, смотри выше.

  3. Да.

0

По вопросам рекламы [email protected]