我们知道,可以在类结构中初始化整数const静态成员。这在初始化后在类结构中使用常量时很有用。例如,它可以用作int的大小阵列。 请查看以下代码:
class MyClass{
static const int num = 100;
int elems[num];
...
};
但我们仍然需要在类定义之外定义成员 num :
const int MyClass::num;
我不知道为什么我们要这样做。 有人能告诉我为什么吗? 非常感谢。
另外,我写了以下代码:
#include <iostream>
using namespace std;
class MyClass{
public:
MyClass()
{
cout << "instruct class MyClass!" << endl;
}
static const int num = 100;
int elems[num];
};
//const int MyClass::num;
int main()
{
MyClass a;
const int *b = &(a.num);
cout << "&(a.num): " << &(a.num) << endl;
cout << "a.num: " << a.num << endl;
cout << "*b: " << *b << endl;
}
它在Visual Studio 2008上运行良好:
但是我删除了在类外定义成员 num 的代码。
我很困惑。有人能为我解释一下吗?
答案 0 :(得分:5)
类中的初始化主要用于获取常量表达式。为此,只有价值才重要。获取对象的地址或将其绑定到引用后,编译器也需要该对象的位置。这实际上是定义提供的内容。
答案 1 :(得分:4)
只有在代码获取地址时,才需要在cpp文件中定义类外的静态常量num
。这称为类外定义。
如果您的代码未使用num
的地址,那么类内初始化就可以正常工作了。
理由:
Bjarne states:
“C ++要求每个对象都有一个唯一的定义。如果C ++允许将需要作为对象存储在内存中的实体的类内定义,那么该规则就会被破坏。”
请注意,只有static const
个整数可以被视为编译时常量。编译器知道整数值不会随时改变,因此它可以应用自己的魔法并应用优化,编译器只是内联这样的类成员,即它们不再存储在内存中,因为需要存储在内存中被删除,它给这些变量提供了Bjarne提到的上述规则的例外。
即使static const
整数值可以具有类内初始化,也不允许获取此类变量的地址。如果(并且仅当)它具有类外定义,则可以获取静态成员的地址,因为编译器需要将它们放在内存中。