10

クラスのインスタンスを作成した後、コンストラクターを明示的に呼び出すことができますか? 例えば

class A{
    A(int a)
    {
    }
}

A instance;

instance.A(2);

これはできますか?

4

7 に答える 7

15

許可する配置 newを使用できます

new (&instance) A(2);

ただし、あなたの例では、オブジェクトのコンストラクターを 2 回呼び出すことになりますが、これは非常に悪い習慣です。代わりに、私はあなたがすることをお勧めします

A instance(2);

配置 new は、通常、メモリを事前に割り当て (カスタム メモリ マネージャなどで)、後でオブジェクトを構築する必要がある場合にのみ使用されます。

于 2008-11-24T11:04:49.853 に答える
10

いいえ。

セットのメソッドを作成し、コンストラクターから呼び出します。このメソッドは、後で使用することもできます。

class A{
    A(int a) { Set(a); }
    void Set(int a) { }
}

A instance;

instance.Set(2);

また、デフォルト値またはデフォルト コンストラクターも必要になるでしょう。

于 2008-11-24T11:18:28.437 に答える
4

いいえ

Calling instance.A() or A(1) is seens as casting  'function-style cast' : illegal as right side of '.' operator

通常、オブジェクトが構築された後だけでなくコンストラクターでも関数/機能が必要な場合、それは init() メソッドに配置され、コンストラクターや他の場所でも使用されます。

例:

 class A{
      A(int a)
       { 
        init(a);
       }

     void init(int a) { } 
     }

        A instance;

        instance.init(2);
于 2008-11-24T11:51:11.787 に答える
3

私はあなたがそれをすることができないと確信しています。それが要点です。コンストラクターはクラスのインスタンスの作成です。

コンストラクターがまったく呼び出されないか、2 回呼び出された場合、どのような結果が生じる可能性がありますか?

もちろんできることは、いくつかのコンストラクター ロジックをメソッドに抽出し、コンストラクター内とオブジェクトの作成後の両方でそのメソッドを呼び出すことです。

于 2008-11-24T11:08:46.523 に答える
1

ちなみに、これは設計上の欠陥のように聞こえます。オブジェクトが構築されると、それを再構築する必要はありません。このような変数名の再利用により、コードが理解しにくくなります。そのため、追加の関数を介してコンストラクターのような機能を利用できるようにするinitset、しばしば間違っています (ただし、避けられない場合もあります)。

Michael が言ったように、placement new はここで使用できますが、実際には別の用途を意図しています。また、メモリの場所に新しいオブジェクトを構築する前に、古いオブジェクトを明示的に破棄する必要があります。

instance.~A();

また、placement newオーバーロードは、渡されたメモリがヒープに属していると想定する可能性があるため、メモリに悪影響を与える可能性があります! 結論として、しないでください。行う。これ。

編集デストラクタの呼び出し本当に必要であることを示すために (POD 以外の場合)、次のコード例を検討してください。

#include <iostream>

struct A {
    A(int a) { std::cerr << "cons " << a << std::endl; }
    ~A() { std::cerr << "dest" << std::endl; }
};

int main() {
    A instance(2);
    new (&instance) A(3);
}

予想どおり、プログラムの結果は次のようになります。

cons 2
cons 3
dest

…つまり、最初のオブジェクトのデストラクタは呼び出されませんA取得した可能性のあるリソースについても同じことが言えます。

于 2008-11-24T18:50:35.357 に答える
0

いいえ、それはできません。コンストラクターを呼び出す唯一の方法は、キーワード「new」によるものです。

于 2009-03-18T05:38:19.767 に答える
-1

要約すると、明示的なコンストラクターを指定する 3 つの方法は次のとおりです。

  1. インスタンス (2); // A インスタンス = 2 を実行します。今まで働いたことがありますか?

  2. *インスタンス = 新しい A(2); // & と * については確信が持てない

  3. 新しい (&instance) A(2);

そしてそれらの味。アイデアの目標は、適切な初期化状態にないオブジェクトが構築されないようにすることであり、コンストラクターはそれを保証するように設計されています。(これは、いくつかの .init(...) メソッドが正常に呼び出されたかどうかをメソッドがチェックする必要がないことを意味します。)

これは、特にフレームワークの一部であり、ライブラリで再利用されるクラスの場合、これを実現するためのより機能的な方法だと思います。これに関心がある場合は、デフォルトのコンストラクターを含むすべてのコンストラクターが完全に機能するインスタンスを提供するように取り組んでください。

例外ケース: コンストラクターから例外をスローすることが適切でない限り、失敗する可能性がある場合、コンストラクター操作に含まれていないものがあります。また、後続のメソッドを使用して伝播される「空の」インスタンスや、初期化メンバーに公開されることを好む人もいます。このような状況を緩和する方法を探り、メソッドの実装や使用において保護する必要がある悪い状態を持たない堅牢なインスタンスを用意することは興味深いことです。

PS: いくつかの複雑なケースでは、初期化されたインスタンス (参照) を関数または「ファクトリ」クラスのメソッドの結果として配信して、中間のセットアップ中のインスタンスが表示されないようにすることが役立つ場合があります。カプセル化ファクトリ クラス インスタンスまたは関数の外側。それは私たちに、

+4。*インスタンス = MakeAnA(2);

+5. *インスタンス = InterestingClass.A(2);

于 2008-11-24T18:27:58.820 に答える