2017-10-25 8 views
1

現在、クラス(myClass)のメンバーをBaseクラスの派生クラス(Derived1、Derived2、...)に設定しようとしています。クラスはそれがどの派生クラスであるか分からないので、メンバ型はBaseクラスに設定され、構築時に派生クラスにのみ設定されます。「未知」の派生クラスを基本クラスとしてメンバーとして宣言し、派生バージョンのメンバー関数を呼び出す方法を教えてください。

派生クラスはすべて、別々に実装された共通メンバー関数を持ちます(基本クラスには仮想バージョンがあります)。ただし、この関数がmyClassから呼び出されると、派生クラスではなく、常にBaseクラスのバージョンが呼び出されます。

class Base 
{ 
public: 
    Base(){} 
    virtual void who() { cout << "this is Base"; } 
} 

class Derived1 : public Base 
{ 
public: 
    Derived1() : Base() {} 
    void who() { cout << "this is Derived1"; } 
} 

class myClass 
{ 
private: 
    Base unknownDerived; 
public: 
    myClass(const Base& inputDerived) { unknownDerived = inputDerived; } 
    void whosthere() { unknownDerived.who(); } 
} 

上記の出力は「This is Base」で、代わりにBaseクラスのバージョンが呼び出されます。

実際の派生クラスを指定せずにメンバーを含めることはできますが、特定の関数(who())を呼び出すことはできますか?

ありがとう!

+0

このコードの実行方法は表示されません。 'メイン 'を含めてください –

+3

あなたの未知の未知数は[スライス]されています(https://en.wikipedia.org/wiki/Object_slicing) – Kevin

+0

@MadPhysicistメインは です。 test.whosthere(); ' – alam

答えて

4

Baseをメンバーとして宣言すると、Baseは実際に得られるものです。派生型を割り当てたとしても、派生したオブジェクトのBase部分だけがコピーされ、オブジェクトは引き続きBaseである「スライス」と呼ばれるものがあります。

C++では、多型はポインタ参照によってのみ機能します。

myClassで実際のメンバーオブジェクト(オブジェクトへの間接参照ではない)を作成するには、myClassにテンプレートパラメータを設定し、コンパイル時にどの型にするかを決定する必要があります。それ以外の場合は、ポインタおよび/または参照を使用する必要があります。

ここで、メモリの所有権と適切なクリーンアップについて明確にする必要があります。呼び出し元が(unique_ptrを取って)オブジェクトの所有権を移転させるか、オブジェクトのディープコピーを作成する仮想clone()関数がBaseにあると主張するかもしれません。さらに、基本クラスにも仮想デストラクタが必要になるでしょう。

+0

ポインタで動作します、ありがとう! – alam

関連する問題