0

私はC++(Javaから来ています)を学んでいます、そしてこれは私から地獄を悩ませています、私が持っていると言います...

class Foo {

public:

    Bar &x; // <- This is a ref, Bar is not instantiated (this is just a placeholder)
    Bar *y; // <- This is a pointer, Bar is not instantiated (this is just another placeholder)
    Bar z;  // <- What is this???

};

class Bar {

public:

    Bar(int bunchOfCrap, int thatNeedsToBeHere, double toMakeABar);

};

この例では、Barに「Bar」を作成するために指定された一連のフィールドを必要とするコンストラクターが1つあります。xもyもバーを作成しません。xはバーを指すことができる参照を作成し、yはバーを表すこともできるポインターを作成することを理解しています。

私が理解していないのは、正確にzが何であるかです。

  • それはバーですか?もしそうなら、どうすればBarの唯一のコンストラクターを与えることができますか?

  • バーに初期化できるのは、Fooのインスタンスに属するバーサイズのメモリのチャンクですか?

  • それとも何か他のものですか?

ありがとう!

4

4 に答える 4

3

教育上の理由から、このコードをコンパイルしてみましょう。

class Bar {
public:
    Bar(int bunchOfCrap, int thatNeedsToBeHere, double toMakeABar);
};

class Foo {
public:
    Bar &x; // <- This is a ref, Bar is not instantiated (this is just a placeholder)
    Bar *y; // <- This is a pointer, Bar is not instantiated (this is just a *safer* placeholder)
    Bar z;  // <- What is this???
};

int main() {
    Foo foo;
}

出力:

c++     uuu.cpp   -o uuu
uuu.cpp:10:7: error: implicit default constructor for 'Foo' must explicitly initialize the reference member 'x'
class Foo {
      ^
uuu.cpp:14:10: note: declared here
    Bar &x; // <- This is a ref, Bar is not instantiated (this is just a placeholder)
         ^
uuu.cpp:10:7: error: implicit default constructor for 'Foo' must explicitly initialize the member 'z' which does not
      have a default constructor
class Foo {
      ^
uuu.cpp:16:9: note: member is declared here
    Bar z;  // <- What is this???
        ^
uuu.cpp:2:7: note: 'Bar' declared here
class Bar {
      ^
uuu.cpp:21:9: note: implicit default constructor for 'Foo' first required here
    Foo foo;
        ^
2 errors generated.
make: *** [uuu] Error 1

それが言うように、デフォルトのコンストラクターがないため、メンバー参照とメンバー変数の両方を初期化する必要があります。初期化する必要はなく、デフォルトで。になります。Bar &xBar z;BaryNULL

xと間接y的にオブジェクトを参照します。参照するものを変更することはできませんx(したがって、がインスタンス化されるときに初期化する必要がFooあります)。参照するものを変更できますyz内部に存在するBarサイズのメモリのチャンクFooです。このようなメンバー変数を合法的に宣言するには、コンパイラーがその大きさを認識できるように、Barbeforeの完全な定義を配置する必要があります。FooBar

于 2013-02-14T03:17:36.960 に答える
1

zはのインスタンスであり、の場合Barに構築する必要がありますFoo。したがって、次のようになります。

class Foo {
public:
    Foo(…)
        : x(<instance of or reference to Bar>),
          y(<pointer to Bar>), // optional
          z(<Bar ctor params>)
    { … }

xとの両方を構築中に初期化する必要があることに注意してくださいz。一方、の初期化を省略することは(疑わしいとはいえ)合法yです。

z親インスタンスと同じメモリを占有しFooますが、これはのインスタンスでありBar、単なるBarサイズのメモリチャンクではありません。

于 2013-02-14T03:12:49.773 に答える
1
  1. はい、それはバーです:タイプz識別子ですBar。デフォルトのコンストラクターを定義していない場合、これによりコンパイラーエラーが生成されます(コンパイラーは通常これを行いますが、少なくとも1つの構造体を定義している場合は発生しません->)。
  2. はい、それはバーサイズのメモリのチャンクであり、が割り当てられたときFooに割り当てられます。
于 2013-02-14T03:13:07.323 に答える
1

それはバーですか?もしそうなら、どうすればBarの唯一のコンストラクターを与えることができますか?

はい、zはバーです。Barデフォルトのコンストラクタがない場合はBar、Fooで初期化する必要がありますmember initializers list。以下のサンプルは、x、yの初期化を無視しています。

Foo::Foo(int param1, int param2, int param3)
: z(param1, param2, param3)
{
}

バーに初期化できるのは、Fooのインスタンスに属するバーサイズのメモリのチャンクですか?

はい、BarオブジェクトはFooオブジェクト内に配置されています

于 2013-02-14T03:14:19.430 に答える