2

一度は基本クラスコンストラクターで派生クラスの上書きされた関数を呼び出すことができないので、この動作エミュレートしたいと思います(C#、Java、...が内部で行っていることと同様です)。

私が(署名の観点から)思いつくことができる最もエレガントなものは次のとおりです。

class Base {
protected:
    virtual void init() {
    }

    template <typename T, typename ...U>
    T internal_create(U&& u) {
        T instance(std::forward<U>(u)...);
        instance.init();
        return instance;
    }
};

class Derived : public Base {
protected:
    Derived() = default;
    virtual void init() override {
    }
public:
    static Derived create() {
        return internal_create<Derived>();
    }


};

Whereは、(パブリックの観点createから)コンストラクターの代わりとして機能し、オブジェクトをインスタンス化する唯一の方法です。問題は、すべての派生クラスがを実装する必要があるため、これをより簡単に実現できるかどうかです。create

4

1 に答える 1

4

あなたのコードがコンパイルされるのがわかりません。そして、仮想メソッドのポイントはわかりませんinitが、2フェーズの構築を示唆しています。これはまさに悪であり、BjarneStroustrupの「C++プログラミング言語」の付録E、特にセクションE3.5を読むことで詳しく知ることができます。

基本クラスコンストラクターで派生クラスの初期化を行うための通常の方法は、FAQに概説されています。私はかつてマーシャルにそのFAQアイテムを追加するように説得したので、私自身のブログにも気軽に案内します。

将来的には、最初にFAQを確認することをお勧めします。


ああ、忘れました。構築中の動的型のC++規則に関するポイントは、型に安全な構築を提供することです。JavaとC#では、派生クラスの初期化されていないメンバーにアクセスしているが、C++ではアクセスしていないというバグを簡単に導入できます。

2フェーズ構造は、型安全性を捨て、例外安全な使用法コードを書くことを困難にします。その見返りとして、1990年代初頭のコンパイラー(しかし実際には、その能力を必要とする人)のためにそれをきれいにコード化する能力があります。

他の通常の解決策は、型の安全性を維持するように設計されています。

于 2012-09-20T02:35:59.130 に答える