web-dev-qa-db-ja.com

別のコンストラクターからC ++クラスコンストラクターを呼び出す方法

複数のオブジェクトコンストラクターを必要とするオブジェクトをC++で作成しようとしています。 Foo()Foo(int)を言います。ここで、Foo(int)Foo()を呼び出します。簡略化したコードを以下に示します。

_#include <iostream>
class Foo{

private:
        int iX; 

public:
        void printX(string sLabel){
            cout << sLabel << " : " << " Foo::iX = " << Foo::iX << endl;
        };  
        void setX(int iX){
            Foo::iX = iX; 
            Foo::printX("setX(void) Method");
        };  
        Foo(){
            Foo::iX = 1;
            Foo::printX("Foo(void) Constructor");
        };
        Foo(int iX){
            Foo::setX(iX);
            Foo::printX("Foo(int) Constructor");
            Foo::Foo();
            Foo::printX("Foo(int) Constructor");

        };  
};

int main( int argc, char** argv ){

    Foo bar(2);

    return 0;
}
_

その出力は

_setX(void) Method :  Foo::iX = 2
Foo(int) Constructor :  Foo::iX = 2
Foo(void) Constructor :  Foo::iX = 1
Foo(int) Constructor :  Foo::iX = 2
_

結果が示すように、setXメソッドは期待どおりに機能します。 _Foo::iX_は、その関数のスコープの内外で_2_と同じです。

ただし、Foo(void)コンストラクター内からFoo(int)コンストラクターを呼び出す場合、_Foo::iX_は、そのコンストラクター内でのみ_1_と等しくなります。そのメソッドを終了するとすぐに、_2_に戻ります。

だから私の質問は2つあります:

  1. なぜC++はこれを行うのですか(割り当てられた値がないと、コンストラクターを別のコンストラクター内から呼び出すことはできません)?
  2. どのようにして複数のコンストラクター署名を作成できますが、同じことを行う重複した重複コードはありませんか?
6
WoodMath

Foo::Foo();Foo::Foo(int)が、現在のオブジェクトのデフォルトコンストラクターを期待どおりに呼び出していません。現在のオブジェクトとは関係のない一時的なFooを作成するだけです。

次のように 委任コンストラクタ (C++ 11以降)を使用できます。

_Foo(int iX) : Foo() {
    // ...
}; 
_

ここでは、Foo::Foo()の本体の前にFoo::Foo(int)が呼び出されることに注意してください。

重複するコードを回避するための代替手段は、setX()を一般的な初期化メソッドとして使用することです。 (または適切でない場合は、新しいものを作成します。)

_Foo() {
    setX(1);
    // ...
};
Foo(int iX) {
    setX(iX);
    // ...
}; 
_
11
songyuanyao

C++ 11コンパイラを使用できる場合は、委任コンストラクタを使用できます。

// Use Foo(int) to initialize the object when default constructor is used.
Foo() : Foo(1) {}
4
R Sahu

コンストラクターは、別のコンストラクター内から呼び出すことができます。戻り値を割り当てるのを忘れるだけです。

*this = Foo::Foo();

質問2では、 委任コンストラクター が必要です。

Foo(int iX) : Foo() {
    ...
}
3
Wiki Wang