在c++中初始化私有静态数据成员的最佳方法是什么?我在头文件中尝试了这一点,但它给了我奇怪的链接器错误:
class foo
{
private:
static int i;
};
int foo::i = 0;
我猜这是因为我不能从类外部初始化一个私有成员。那么最好的方法是什么呢?
在c++中初始化私有静态数据成员的最佳方法是什么?我在头文件中尝试了这一点,但它给了我奇怪的链接器错误:
class foo
{
private:
static int i;
};
int foo::i = 0;
我猜这是因为我不能从类外部初始化一个私有成员。那么最好的方法是什么呢?
当前回答
也在privatstatic .cpp文件中工作:
#include <iostream>
using namespace std;
class A
{
private:
static int v;
};
int A::v = 10; // possible initializing
int main()
{
A a;
//cout << A::v << endl; // no access because of private scope
return 0;
}
// g++ privateStatic.cpp -o privateStatic && ./privateStatic
其他回答
类声明应该在头文件中(如果不共享,则在源文件中)。 文件:foo。
class foo
{
private:
static int i;
};
但是初始化应该在源文件中。 文件:foo.cpp
int foo::i = 0;
如果初始化是在头文件中,那么每个包含头文件的文件都有一个静态成员的定义。因此,在链接阶段,你会得到链接器错误,因为初始化变量的代码将在多个源文件中定义。 静态int i的初始化必须在任何函数之外完成。
注意:Matt Curtis:指出,如果静态成员变量是const整数类型(bool, char, char8_t[自c++ 20以来],char16_t, char32_t, wchar_t, short, int, long, long long,或任何实现定义的扩展整数类型,包括任何有符号,无符号和cv限定变量),c++允许简化上述内容。然后你可以直接在头文件的类声明中声明和初始化成员变量:
class foo
{
private:
static int const i = 42;
};
如果使用头保护,也可以在头文件中包含赋值。我在自己创建的c++库中使用了这种技术。实现相同结果的另一种方法是使用静态方法。例如……
class Foo
{
public:
int GetMyStatic() const
{
return *MyStatic();
}
private:
static int* MyStatic()
{
static int mStatic = 0;
return &mStatic;
}
}
上面的代码有一个“好处”,就是不需要CPP/源文件。同样,这是我在c++库中使用的方法。
从c++ 17开始,静态成员可以在头文件中用inline关键字定义。
http://en.cppreference.com/w/cpp/language/static
静态数据成员可以内联声明。内联静态数据成员可以在类定义中定义,并且可以指定默认成员初始化式。它不需要一个类外定义:
struct X
{
inline static int n = 1;
};
使用Microsoft编译器[1],不像int型的静态变量也可以在头文件中定义,但在类声明之外,使用Microsoft特定的__declspec(selectany)。
class A
{
static B b;
}
__declspec(selectany) A::b;
请注意,我并不是说这是好的,我只是说这是可以做到的。
现在,比MSC更多的编译器支持__declspec(selectany)——至少gcc和clang。甚至更多。
也在privatstatic .cpp文件中工作:
#include <iostream>
using namespace std;
class A
{
private:
static int v;
};
int A::v = 10; // possible initializing
int main()
{
A a;
//cout << A::v << endl; // no access because of private scope
return 0;
}
// g++ privateStatic.cpp -o privateStatic && ./privateStatic