C++:外部 class 中内部 class 的静态实例
C++: static instance of inner class in outer class
我写了一段代码如下。
这里有一个外class和一个内class。
我想要一个类似于 java 的 inner static class 的功能。
所以我将内部 class 对象声明为静态的。
输出很好:
#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();
编辑:我该如何初始化内部 class 的实例呢?
另外,当我在下面分配时出现分段错误,这可能是因为自我分配。
x.i = 5;
这是静态变量的定义X::z
。如果稍后在要求数据成员存在于物理内存中的上下文中使用某些静态数据成员,则需要命名空间范围定义。
定义具有普通变量声明的格式,除了它的名称被限定以表示它是一个静态成员:
X::Z
是成员的类型,X::z
是指定其名称的qualified-id。此语句将其值初始化为静态成员函数 X::getZ()
的 return 值,它本身就是
请注意,此未定义行为自 X::getZ()
returns z
以来处于未初始化状态。
由于z
是静态成员变量,所以需要定义。您正在查看的代码行就是该定义。
X::Z X::z = X::getZ();
X::Z
(注意大写Z
)是类型,X::z
(注意小写z
)是变量,由return X::getZ()
静态成员函数的值。
事实证明 X::getZ()
只是 returning X::z
。尽管它看起来多余,但它抑制了 X::z
的默认构造函数的执行,而是使用复制构造函数。
静态对象在执行静态初始化之前被零初始化。如果对象通过零初始化正确初始化,则 self 上的复制构造函数不会造成任何特别的伤害。但是,在这种情况下 X::Z
有一个引用成员变量 x
,它被初始化为零。访问 x
会导致未定义的行为。
您添加了一个关于正确初始化静态成员的附加问题z
。
由于您以 X::getZ()
的形式为 z
提供访问器方法,更好的解决方案是避免使用静态成员变量,并在 [=17= 中放置一个静态实例] 函数本身。由于 z
需要 X
的一个实例才能正确初始化,因此应该提供一个。
class X {
//...
public:
static Z & getZ() {
static X x;
static Z z(x);
return z;
}
private:
int i;
};
X::getZ()
的 return 类型更改为对静态实例的引用,以便可以操作该实例。
I am not able to understand this statement though.
这是在classX
中声明的静态变量的定义。以下是每个部分的含义:
X::Z
表示定义的静态数据成员的类型是Z
,定义在classX
. 里面
X::z
表示我们正在定义一个名为 z
的静态成员,声明在 class X
中
= X::getZ()
表示z
要初始化为getZ()
成员函数返回的值。
但是,这不是一个好的代码,因为 getZ
在变量有机会被初始化之前使用它初始化的 z
。
我写了一段代码如下。 这里有一个外class和一个内class。 我想要一个类似于 java 的 inner static class 的功能。 所以我将内部 class 对象声明为静态的。 输出很好:
#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();
编辑:我该如何初始化内部 class 的实例呢? 另外,当我在下面分配时出现分段错误,这可能是因为自我分配。
x.i = 5;
这是静态变量的定义X::z
。如果稍后在要求数据成员存在于物理内存中的上下文中使用某些静态数据成员,则需要命名空间范围定义。
定义具有普通变量声明的格式,除了它的名称被限定以表示它是一个静态成员:
X::Z
是成员的类型,X::z
是指定其名称的qualified-id。此语句将其值初始化为静态成员函数 X::getZ()
的 return 值,它本身就是
请注意,此未定义行为自 X::getZ()
returns z
以来处于未初始化状态。
由于z
是静态成员变量,所以需要定义。您正在查看的代码行就是该定义。
X::Z X::z = X::getZ();
X::Z
(注意大写Z
)是类型,X::z
(注意小写z
)是变量,由return X::getZ()
静态成员函数的值。
事实证明 X::getZ()
只是 returning X::z
。尽管它看起来多余,但它抑制了 X::z
的默认构造函数的执行,而是使用复制构造函数。
静态对象在执行静态初始化之前被零初始化。如果对象通过零初始化正确初始化,则 self 上的复制构造函数不会造成任何特别的伤害。但是,在这种情况下 X::Z
有一个引用成员变量 x
,它被初始化为零。访问 x
会导致未定义的行为。
您添加了一个关于正确初始化静态成员的附加问题z
。
由于您以 X::getZ()
的形式为 z
提供访问器方法,更好的解决方案是避免使用静态成员变量,并在 [=17= 中放置一个静态实例] 函数本身。由于 z
需要 X
的一个实例才能正确初始化,因此应该提供一个。
class X {
//...
public:
static Z & getZ() {
static X x;
static Z z(x);
return z;
}
private:
int i;
};
X::getZ()
的 return 类型更改为对静态实例的引用,以便可以操作该实例。
I am not able to understand this statement though.
这是在classX
中声明的静态变量的定义。以下是每个部分的含义:
X::Z
表示定义的静态数据成员的类型是Z
,定义在classX
. 里面
X::z
表示我们正在定义一个名为z
的静态成员,声明在 classX
中
= X::getZ()
表示z
要初始化为getZ()
成员函数返回的值。
但是,这不是一个好的代码,因为 getZ
在变量有机会被初始化之前使用它初始化的 z
。