C++成员变量混淆

C++ Member variables confusion

本文关键字:变量 成员 C++      更新时间:2023-10-16

我正在学习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"。x和y都没有创建Bar,我知道x创建了一个可以指向Bar的引用,而y创建的指针也可以表示Bar。

我不明白z到底是什么。

  • 这是酒吧吗?如果是这样的话,怎么能给它一个Bar唯一的构造函数呢?

  • 它是属于Foo实例的Bar大小的内存块,可以初始化为Bar吗?

  • 还是别的什么?

谢谢!

出于教学原因,让我们尝试编译以下代码:

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 &x和成员变量Bar z;,因为Bar没有默认构造函数。y不必初始化,它将默认为NULL

xy都间接引用对象。您无法更改x所指的内容(因此必须在实例化Foo时对其进行初始化)。您可以更改y所指的内容。z是位于Foo内部的Bar大小的内存块;要合法地声明这样的成员变量,必须将Bar的完整定义放在Foo之前,这样编译器才能知道Bar有多大

  1. 是的,它是一个条形:z是类型为Bar标识符。如果您没有定义默认构造函数,这将生成编译器错误(编译器通常会这样做,但如果您至少定义了一个已定义的构造->,则不会这样做)
  2. 是的,它是一个条形大小的内存块,在分配Foo时分配

这是酒吧吗?如果是这样的话,怎么能给它一个Bar唯一的构造函数呢?

是的,z是一家酒吧。如果Bar没有默认构造函数,则必须在Foo member initializers list中初始化Bar。以下示例忽略x,y初始化:

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

它是属于Foo实例的Bar大小的内存块,可以初始化为Bar吗?

是的,Bar对象在Foo对象内对齐

zBar的实例,必须在Foo为时构造,因此:

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

请注意,xz都必须在构造期间初始化,而省略y的初始化是合法的(尽管有问题)。

z占用与父Foo实例相同的内存,但它是Bar的实例,而不仅仅是Bar大小的内存块。