2016-10-07 5 views
2

関与する複数の継承せずに、単純な階層があるとしますC++でポリモーフィックな追加init()関数を作成するには?

a)は、すべてのderived_x::init()

base::init()を繰り返す:

class base { 
public: 
    base() { /* */ } 
    virtual void init() { /* */ } 
}; 

class derived_a : public base { 
public: 
    derived_a() { /* */ } 
    virtual void init() override { base::init(); /* local stuff to add */ } 
}; 

class derived_b : public base { 
public: 
    derived_b() { /* */ } 
    virtual void init() override { base::init(); /* local stuff to add */ } 
}; 

そして、クライアントコードは、私は二つの問題を参照してください

auto d_a = new derived_a{}; 
d_a->init(); 

のようになります

b)毎回derived_x::init()を繰り返して、オブジェクトが作成されます

どちらも私の観点からは簡単に忘れられます。

base::base{}では、baseで、derived_xではなく、C++での仮想ディスパッチの仕組みを知っています。しかし、回避策がありますか?ありませんか?開発者が何度も直面してきた共通の問題のように見えます。可能な解決策とは何ですか?

+2

2段階初期化が悪いですが、これを行わないでください。基本クラスに保護されたコンストラクタを追加して、初期化の共通部分を行い、派生したクラスコンストラクタから必要な引数を渡すことができます。 – sbabbi

+0

これはコンストラクタが自動的にあなたのために行うものです。 –

+1

コンストラクタに初期化コードを追加し、 'init()'を削除して2フェーズの初期化を行わないと、コンストラクタは派生クラスコンストラクタの前に常に呼び出されます。派生クラスのインスタンス – Peter

答えて

5

あなたが強制的に一緒に暮らすことができる場合ユーザーのファクトリ関数の使用は、あなたが階層の最下位にファイナライザクラステンプレートを追加することができます

template<typename T> 
class base_finalizer : public T 
{ 
    base_finalizer() 
    { 
     this->base::init(); 
     this->T::init(); 
    } 
}; 

template<typename T> 
auto make_base() 
{ 
    return unique_ptr<T>(new base_finalizer<T>); 
} 

これはまた、あなたがそれを必要とする場合は、あなたのbase_finalizerは、オブジェクトの最後の動的な型を使用して、いくつかのクリーンアップを行うことができます。

これは、シンプルな値のセマンティクスであなたの型を利用できるようにするために常に努力していると言われています。

+0

スマート!それは私のことではありませんが、CRTPを思い出させます。 – iksemyonov

+0

@iksemyonovありがとう。私は実際に私のプロジェクトでこれを使用しています。かなりうまく実行されています( 'Derived 'が破棄されたときに、それらのイベントで必要なオブジェクトが外れる前に' Base'の 'QThread'イベント処理を終了するために使用します)。 – krzaq

+0

Aren' 'QThread'をサブクラス化するのではなく、' moveToThread() 'を期待していましたか?私は例外があると思いますが、そうする重大な理由があります。それとも、サブクラス化せず、私は誤読していますか? – iksemyonov

2

慣用的な解決法は、全く方法を持たないものとする。initそこに起こるすべてはinit機能が触れるであろうと(いくつかのコンストラクタでbaseまたはderived_*クラスまたはメンバーのいずれかが起こるはずです。

この方法は、それは忘れてすることはできません。

+0

本当に、コンストラクターがその目的のために正確に存在しているということは私には起こりませんでした。 – iksemyonov

関連する問題