是否可以在构造函数之外初始化静态常量值?可以在成员声明所在的地方进行初始化吗?
class A {
private:
static const int a = 4;
/*...*/
};
是的,你可以,但仅限于 int 类型。 如果您希望静态成员是任何其他类型,则必须在 cpp 文件中的某个位置定义它。
class A{
private:
static const int a = 4; // valid
static const std::string t ; // can't be initialized here
...
...
};
// in a cpp file where the static variable will exist
const std::string A::t = "this way it works";
另请注意,此规则已在 C++11 中删除,现在(使用提供该功能的编译器)您可以直接在类成员声明中初始化您想要的内容。
类的成员列表中静态数据成员的声明不是定义。您必须在类声明之外、命名空间范围内定义静态成员。例如:
class X
{
public:
static int i;
};
int X::i = 0; // definition outside class declaration
一旦定义了静态数据成员,即使静态数据成员的类的对象不存在,它也存在。在上面的示例中,即使定义了静态数据成员 X::i,类 X 的对象也不存在。
命名空间范围内的类的静态数据成员具有外部链接。静态数据成员的初始值设定项位于声明该成员的类的范围内。
静态数据成员可以是除 void 或用 const 或 volatile 限定的 void 之外的任何类型。您不能将静态数据成员声明为可变的。
程序中只能有一个静态成员的定义。未命名类、未命名类中包含的类以及本地类不能有静态数据成员。
静态数据成员及其初始值设定项可以访问其类的其他静态私有和受保护成员。以下示例显示如何使用其他静态成员初始化静态成员,即使这些成员是私有的:
class C {
static int i;
static int j;
static int k;
static int l;
static int m;
static int n;
static int p;
static int q;
static int r;
static int s;
static int f() { return 0; }
int a;
public:
C() { a = 0; }
};
C c;
int C::i = C::f(); // initialize with static member function
int C::j = C::i; // initialize with another static data member
int C::k = c.f(); // initialize with member function from an object
int C::l = c.j; // initialize with data member from an object
int C::s = c.a; // initialize with nonstatic data member
int C::r = 1; // initialize with a constant value
class Y : private C {} y;
int C::m = Y::f();
int C::n = Y::r;
int C::p = y.r; // error
int C::q = y.f(); // error
C::p 和 C::q 的初始化会导致错误,因为 y 是从 C 私有派生的类的对象,并且 C 的成员无法访问其成员。
如果静态数据成员是const整型或const枚举类型,则可以在静态数据成员的声明中指定常量初始值设定项。该常量初始值设定项必须是整型常量表达式。请注意,常量初始值设定项不是定义。您仍然需要在封闭的命名空间中定义静态成员。以下示例演示了这一点:
#include <iostream>
using namespace std;
struct X {
static const int a = 76;
};
const int X::a;
int main() {
cout << X::a << endl;
}
静态数据成员 a 声明末尾的 tokens = 76 是常量初始值设定项。
为了完整起见,我添加了静态模板成员变量。
template<class T> struct X{
static T x;
};
template<class T> T X<T>::x = T();
int main(){
X<int> x;
}
您无法在构造函数中初始化静态成员。您可以在声明时内联初始化整型类型。其他静态成员必须定义(在
.cpp
)文件中:
// .h
class A{
private:
static const int a = 4;
static const foo bar;
...
...
};
// .cpp
const foo A::bar = ...;
现代C++
#include <iostream>
class A
{
public:
int GetA()
{
return a_;
}
private:
const static int a_{ 4 }; // (Since C++11)
};
int main()
{
A a{};
std::cout << a.GetA() << std::endl;
}