2

デフォルトを使用して値を初期化し、そのベースをいくつかの特殊なコンストラクターに拡張する「ベース」コンストラクターを定義する方法を探しています。

私が欲しいものの擬似コードは次のようになります。

class Foo{
private:
    int val;
    /* ... */

public:
    // Base constructor
    Foo(){ /*...*/ }           // This provides basic initialization of members

    // Named constructors
    static Foo fromString(string s){
        Foo f;                 // Call base constructor
        f.val = s.length();    // Customize base object
        return f;              // Return customized object
    }
    static Foo fromInt(int v){
        Foo f;
        f.val = v;
        return f;
    }
}

最初は、一時的なの有効期間を延長するfことを考えましたが、const宣言により、そのメンバーを編集できません。だから、これは出ているようです。

次に、 「名前付きコンストラクター」アプローチ(上に表示)を試しました。ただし、最初にオブジェクトを作成するために例を変更し、次にそれを変更してから返す必要がありました。fこれは機能しているように見えますが、これは一時的なものであり、関数の最後で範囲外になるため、これは単なる偶然であると合理的に確信しています。

sのようなものを使用することも検討しましauto_ptrたが、Fooオブジェクトとs to Fooの両方を使用しているauto_ptrため、残りのコードは、オブジェクトがベースコンストラクターを介して作成されているかどうかを「気にします」(この場合)。オブジェクト)または拡張コンストラクターの1つを介して(この場合はポインターになります)。

それが役立つ場合は、Pythonで次のようなものを使用します。

class Foo(object):
    def __init__(self):
        /* Basic initialization */

    @classmethod
    def fromString(cls, s):
        f = Foo() #†
        f.val = len(s)
        return f

最後に、私がこのようにしたい理由は2つあります。

  1. コードの再利用。共通の初期化を各コンストラクターから1つに移動したいと思います。これは、各コンストラクターによって呼び出される-typeプライベートメソッドを介して実行できることに気付きinit()ましたが、これについて言及したかっただけです。
  2. 明確性とあいまいさの解決。名前付きコンストラクターの例の動機と同様に、パラメータータイプだけでは、どのctorを使用するかを決定するのに十分ではありません。さらに、fromSomething構文は優れた明快さを提供します。

簡単な解決策があれば許してください。私の仕事は過去数年間でc++からJava/Pythonに移行しているので、少し錆びています。

4

3 に答える 3

6

これは完全に有効です:

static Foo fromInt(int v){
    Foo f;
    f.val = v;
    return f;
}

Fooこれにより、戻るときにのコピーコンストラクタが呼び出されますf(おそらく、コンパイラは戻り値の最適化を適用するため、コピーは作成されません)。f範囲外になりますが、戻り値はそのコピーにすぎないため、これは完全に有効であり、機能しているのは単なる「偶然の一致」ではありません。

したがって、名前付きコンストラクターアプローチの使用について心配しているのが、それが機能するかどうかが本当にわからない場合は、先に進んでください。完全に機能します。

于 2012-07-06T16:06:22.490 に答える
2

C ++ 11では、コンストラクターから他のコンストラクターを呼び出すことができます。

struct X{
  X() : ... { ... }
  X(int i) : X() { ... }
  X(std::string s) : X() { ... }
};

C ++ 03の場合、名前付きコンストラクターアプローチが最適で完全に合理的である可能性があります。

于 2012-07-06T16:07:10.187 に答える
0

なぜだめですか:

class Foo{
private:
    int val;
    void Init(int v = <some default value>/*What ever here *));
    /* ... */


public:
    // Base constructor
    Foo(){ Init(); }           // This provides basic initialization of 
    Foo(string &s) { Init(s.length); };
    Foo(int v) { Init(v); };
};

簡単そうです。

于 2012-07-06T16:06:01.133 に答える