CPP03 1.0
|
派生クラスScavTrap
の以下のメンバー関数にvirtual
を付けない主な理由は、これらの関数が基底クラス(ClapTrap
) のインターフェースの一部ではなく、ScavTrap
固有の振る舞いや特性を定義しているためです。
それぞれの関数について詳しく見ていきましょう。
ScavTrap();
(デフォルトコンストラクタ)ScavTrap(const std::string &name);
(名前付きコンストラクタ)ScavTrap(const ScavTrap &other);
(コピーコンストラクタ)コンストラクタはオブジェクトの作成を担当する特殊なメンバー関数です。virtual コンストラクタはC++では 許可されていません 。これは、virtual 関数のメカニズムがオブジェクトが既に存在することを前提としているため、オブジェクトがまだ作成されていないコンストラクタには適用できないためです。オブジェクトの型は、コンストラクタが呼び出される際に静的に決定されます。派生クラスのオブジェクトを作成する際には、まず基底クラスのコンストラクタが呼び出され、その後派生クラスのコンストラクタが呼び出されるという明確な順序があります。
コピー代入演算子は、既存のオブジェクトに別のオブジェクトの値を代入するために使用されます。これもコンストラクタと同様に、オブジェクトの型が静的にわかっている状態で呼び出されます。基底クラスのポインタや参照を通じて派生クラスの代入演算子を呼び出すというシナリオは、通常意図されていません。代入は、同じ型のオブジェクト間で行われることが一般的です。もし基底クラスのポインタで派生クラスのオブジェクトを指している場合に代入を行いたいのであれば、通常は基底クラスの代入演算子が呼び出されるべきであり、派生クラス固有の追加の代入処理は派生クラスの代入演算子内で明示的に行う必要があります。
void guardGate()
; (固有のメンバー関数)
guardGate()
関数は、ScavTrap
クラスで 新しく導入 された、ScavTrap
特有の機能 です。基底クラスClapTrap
はこの関数を知りません。したがって、基底クラスのポインタや参照を通じてこの関数を呼び出すことはできません。virtual
関数は、基底クラスで宣言され(あるいは純粋仮想関数として宣言され)、派生クラスでオーバーライドされることで、ポリモーフィズムを実現するものです。guardGate()
は基底クラスに存在しないため、virtual
を付ける意味がありません。ScavTrap
のオブジェクトが直接扱われる場合にのみ呼び出される関数です。
まとめ:
virtual
キーワードは、主に 基底クラスで宣言された関数が、派生クラスのオブジェクトを基底クラスのポインタや参照を通じて操作する際に、派生クラスの実装を呼び出す ために使用されます。
guardGate()
はScavTrap
固有の機能であり、基底クラスに存在しないため、仮想化する必要がありません。これらの理由から、ScavTrap
クラスのこれらのメンバー関数にはvirtual
キーワードは付けられません。