C++:外部类中内部类的静态实例
C++: static instance of inner class in outer class
我写了一些代码,如下所示。 这里有一个外部类和一个内部类。 我想要一个类似于 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
。
- C++两个源文件之间共享的枚举的静态实例
- 宏为模板类静态实例生成有效的标识符
- 我可以在类头文件中定义一个类的const静态实例吗
- 类的静态实例不能调用私有成员函数.C++
- 第二个dll中的静态实例的破坏者未被调用
- 类的静态实例无法在程序退出时正确处理资源删除
- C++:外部类中内部类的静态实例
- 结构定义包含自身的静态实例
- 什么是C++中C#静态实例的等价物
- 父类包含子类C++的静态实例
- 在C++中创建静态实例的未解析外部
- 多个对象的静态实例变量-c++
- 在c++中,一旦程序退出,singleton(静态实例)就会被销毁,这是正确的原因
- 对从静态实例引用的类模板的静态成员的未定义引用
- 在类自身内部创建类的静态实例的正确方法
- 初始化模板类中嵌套类的静态实例
- 卸载c++插件中的静态实例变量
- 在c++ STL类型的静态实例上使用OpenMP threadprivate指令
- 我的类的静态实例函数不像我预期的那样工作
- 保留子类的中心列表,但避免静态实例