1

継承とインターフェイス クラスの混合について投稿された質問がありました: 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_IntfBinary_Stream_Write_Read_Intf同じですか?
  2. 関数呼び出しで一方を他方に置き換えることはできますか?
  3. を必要とする機能に両方を使用できます Binary_Stream_Read_Intfか?
4

2 に答える 2

2

1 いいえ、それらは同じではありません。2 つの異なる名前を持つ 2 つの異なる構造体を宣言しました。コンパイラはそれらを完全に異なるものとして扱います。これは言っているのと同じです。

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 を継承しているので、はい。

于 2013-02-21T18:44:43.007 に答える
0
  1. いいえ、同じように同じstruct Foo {};ではありませんstruct Bar {};

  2. いいえ、上記を参照してください。

  3. はい。

于 2013-02-21T18:25:07.447 に答える