C++:外部类中内部类的静态实例

C++: static instance of inner class in outer class

本文关键字:静态 实例 内部类 外部 C++      更新时间:2023-10-16

我写了一些代码,如下所示。 这里有一个外部类和一个内部类。 我想要一个类似于 java 的内部静态类的功能。 所以我将内部类对象声明为静态。 输出很好:

#include <iostream>
using namespace std;
class X {
private:
X() {}
public:
class Y {
public:
virtual void f() = 0;
};
class Z:public Y {
public:
Z(X& val) : x(val) {}
void f() {
cout << "Programming";
x.i = 5;
}
private:
X& x;
};
static Z getZ() {
return z;
}
private:
static Z z;
int i;
};
X::Z  X::z = X::getZ();
int main()
{
X::getZ().f();
return 0;
}

不过,我无法理解这种说法。它是如何工作的?

X::Z  X::z = X::getZ();

编辑:那么如何初始化内部类的实例呢? 当我在下面分配时,我也遇到了分割错误,这可能是因为自我分配。

x.i = 5;

由于z是一个静态成员变量,因此它需要一个定义。您正在查看的代码行就是该定义。

X::Z  X::z = X::getZ();

X::Z(注意大写Z)是类型,X::z(注意小写z)是变量,它由X::getZ()静态成员函数的返回值初始化。

事实证明,X::getZ()只是在返回X::z.尽管它看起来是多余的,但它禁止执行X::z的默认构造函数,并改用复制构造函数。

在执行静态初始化之前,静态对象的初始化为零。如果对象通过零初始化正确初始化,则 self 上的复制构造函数不会造成任何特别的伤害。但是,在这种情况下,X::Z有一个引用成员变量x该变量初始化为零。访问x会导致未定义的行为。


您添加了有关正确初始化静态成员z的附加问题。

由于您以X::getZ()的形式为z提供了一个访问器方法,因此更好的解决方案是避免使用静态成员变量,并将静态实例放在X::getZ()函数本身中。由于z需要正确初始化X实例,因此应提供一个实例。

class X {
//...
public:
static Z & getZ() {
static X x;
static Z z(x);
return z;
}
private:
int i;
};

X::getZ()的返回类型更改为对静态实例的引用,以便可以操作该实例。

不过我无法理解这种说法。

这是在类X中声明的静态变量的定义。以下是它每个部分的含义:

  • X::Z说被定义的静态数据成员的类型是Z,它是在类X中定义的。
  • X::z意味着我们正在定义一个名为z静态成员,该成员在类X中声明
  • = X::getZ()表示z将初始化为从成员函数返回的值getZ()

但是,这不是一个好的代码,因为getZ在变量有机会初始化之前使用它初始化的z

这是静态变量X::z的定义。如果某些静态数据成员稍后在要求数据成员存在于物理内存中的上下文中使用,则需要命名空间范围定义。

该定义具有普通变量声明的格式,除了它的名称限定为表示它是静态成员:

X::Z是成员的类型,X::z是指定其名称的限定 ID。此语句将其值初始化为静态成员函数X::getZ()的返回值,即自身。

请注意,自X::getZ()年以来,这种未定义的行为将返回处于未初始化状态的z