0

定義内でクラスのインスタンスを作成するにはどうすればよいですか?

class Test{
  Test _test;
};

これはスローします

error: field _test has incomplete type

ポインターの使用は機能しますが、可能であればポインターの使用を避けたいと思います。

4

4 に答える 4

8

そのようなことができると想像してみてください。これは再帰的な定義になります。type のオブジェクトには type のオブジェクトが含まれ、これにはTesttype のオブジェクトが含まれます。ユーザーまたはコンパイラーが夢中になるまで、終了することなく続きます。TestTest

たとえそれがコンパイルされたとしても、あなたがそのようなものを望んでいるとは本当に思いません。一方、ポインターの使用は、次の 2 つの理由から問題ありません。

  • Testポインターは null になる可能性があり、そうでなければ無限に再帰的なオブジェクトのチェーン (実行時に無限のスペースを必要とする)を壊す可能性があります。
  • Testポインターのサイズは固定されているため、コンパイラーはそれ自体のサイズを計算するためにのサイズを計算する必要はありませんTest(コンパイル時に無限再帰が発生します)。

ポインターの使用は機能しますが、可能であればポインターの使用を避けたいと思います。

手動のメモリ管理が心配な場合は、スマート ポインターを使用してください。

#include <memory>

class Test
{
    std::unique_ptr<Test> _test;
};
于 2013-03-05T10:45:38.913 に答える
4

次の質問に答えてください。あなたのクラスはどのくらいの大きさですか?

私が考えることができる唯一の2つの解決策は、ポインターを使用することです。

class Test
{
public:
    Test * data;
};

このソリューションは、リストやツリーなどの高度な構造で一般的です。もう 1 つの方法は、内部フィールドを static として宣言することです。

class Test
{
public:
    Test(int i);

    static Test data;
}

Test Test::data = Test(5);

このソリューションは、シングルトン、マルチトン、または同様の構造に共通です。ただし、インスタンスからではなく、クラスからのみフィールドにアクセスできることに注意してください。

Test test = Test::data;
于 2013-03-05T10:50:58.603 に答える
0

クラスのオブジェクトが作成されると、クラス変数のメモリが初期化されます。しかし、その定義でのみクラスのオブジェクトを作成すると、その時点ではクラスの定義がまだ完了していないため、コンパイラはその時点でクラスの変数を初期化できません。

于 2013-03-05T11:29:16.077 に答える
0

あなたのテストはまだ定義されていないので、どうやってそのインスタンスを作成しますか。確かにポインタを作成できます。ポインタは不完全型なので。そのため、Singleton クラスとリンク リストには参照へのポインターがあり、オブジェクト自体は完全ではありません。

于 2013-03-05T10:48:54.897 に答える