0

私は少し混乱しています:

  • 基本クラス A と、A を拡張するクラス B がある場合、型 A の変数は型 B の値を保持できますか、またその逆は可能ですか?

はいの場合、なぜですか? BがAから派生したとしても、それらはまったく異なるものではありませんか? タイプセーフはどうですか?

  • これが可能である場合、これを使用する際にどのような点に注意する必要がありますか? これは、パフォーマンスの点でどのように機能しますか?

注: 質問が多すぎて申し訳ありません。無視して、リストの装飾ドットで「マーク」されているものに注意してください :) また、これは私の宿題ではありません。私は趣味のプログラマーであり、OOP を使用したスクリプト言語のスキルを持っていますが、C++ での OOP の入力については比較的初心者です。

4

4 に答える 4

3

これを行う場合:

B b;
A a = b;

次に、「スライス」を取得します。 の部分aだけが含まれます。Ab

しかし、参照/ポインタを持つことができます:

B b;
A &ra = b;
A *pa = &b;

この場合、ra実際paBオブジェクトを参照/ポイントするだけです。これは、公開継承が IS-A 関係をモデル化するためです。これは、よりわかりやすい名前で理解しやすくなります。Aと をとAnimal考えてください。IS-Aしたがって、参照/ポインターを使用することで、aをより一般的な型として扱うことができます。BBaboonBaboonAnimalBaboonAnimal

于 2010-05-11T20:59:12.093 に答える
0

反対ではありませんが、パフォーマンスはここで正しい質問ではありません。OO 設計を行うと決めた場合は、パフォーマンスの問題のために正しい抽象化を犠牲にしないでください。時期尚早の最適化は諸悪の根源です。幸運を!

于 2010-05-11T21:19:57.900 に答える
0

タイプ A の変数は、タイプ B の値を保持できます (他の回答が説明するように、「ホールド」の特定の定義について) が、その逆は絶対にありません。標準的な例を分割するには:

class Animal {};
class Dog : public Animal {};
class Cat : public Animal {};

Catから派生するため、これは正当ですAnimal

Cat c;
Animal& a = c;

これはそうではありません:

Animal a;
Cat& c = a;

これは、タイプセーフであるように定義したためです。継承の全体的なポイントは、この種のことが起こることを可能にすることです。そのため、Animalどの基本クラスがたまたまそこに格納されているかを知らなくても、ジェネリック変数でメソッドを呼び出すことができます。パフォーマンスの問題に関しては、仮想メソッドの呼び出しは遅くなります。なぜなら、どのメソッドが実際に呼び出されるかを決定する (Cat::foo()Dog::foo()、たとえば、Animal変数に格納されている特定のタイプに応じて) 実行時に行わなければならないためです。これは動的ディスパッチと呼ばれます。 . 非仮想メソッドでは、コンパイル時に決定が行われる可能性があります

于 2010-05-11T21:00:23.883 に答える
0

class のオブジェクトへのポインタまたは参照Aは、 class のオブジェクトを指す/参照できますB。これは、Bから派生した場合A、 aB Aa であるためです。class の各オブジェクトには、 class のBすべてのメンバー変数と関数にA加えて、 に固有のものがありBます。

class A
{
   public:
      virtual ~A();
      void foo();
};

class B : public A
{
   public:
      void bar();
};

A * a = new B;
a->foo(); // perfectly valid, B inherits foo() from A
//a->bar(); // compile-time error, bar() is only defined in B
delete a; // make sure A has a virtual destructor!

通常、この種のコードは、仮想関数を介してポリモーフィックな動作を利用したい場合に使用されます。

于 2010-05-11T21:02:29.370 に答える