1. ホーム
  2. c++

[解決済み] クラスエラーに対応するデフォルトコンストラクタが存在しない

2022-02-28 03:22:16

質問

簡単なコードです。

class Thing {
public:
    int num;
    Thing(int num) { 
        this->num = num; 
    }
};

class Stuff {
public:
    Thing thing;  // an instance of thing is declared here but it cannot construct it
    Stuff(Thing thing) {
        this->thing = thing;
    }
};

int main() {
    Thing thing = Thing(5);
    Stuff stuff = Stuff(thing);
}

ここでは、Stuffに自分自身のコピーを保持させたいので、StuffのコンストラクタでThingの新しいインスタンスを指すことなく取得する方法について考えているところです。もちろん、thingを初期化しようとしているので、上記のように宣言することはできない。

コンストラクタを通じてクラスの変数に新しいオブジェクトのコピーを代入するこの問題は、どうすれば回避できるのでしょうか?

正確なエラーは

In constructor 'Stuff::Stuff(Thing)':
error: no matching function for call to 'Thing::Thing()'
  Stuff(Thing thing){ this->thing = thing; }

candidate expects 1 argument, 0 provided

解決方法は?

問題はここです。

Stuff(Thing thing) {
    this->thing = thing;
}

コンストラクタの本体に入るまでに、コンパイラはすでにオブジェクトのデータ・メンバを初期化しています。 しかし thing なぜなら、デフォルトのコンストラクタを持たないからです。

解決策は、コンパイラに初期化方法を伝えるために イニシャライザーリスト .

Stuff(Thing thing) : thing(thing) {
    // Nothing left to do.
}

この方が型付けが少なく、コードもすっきりして、効率的です。 (より効率的というのは、変数がどうせ初期化されるのなら、最初に不要な値で初期化して、できるだけ早く別の値を代入する必要はないでしょう? もちろん、今のコードはコンパイルすらできないので、「より効率的」というのはいささか疑わしい表現ですが...)