在c++中初始化私有静态数据成员的最佳方法是什么?我在头文件中尝试了这一点,但它给了我奇怪的链接器错误:

class foo
{
    private:
        static int i;
};

int foo::i = 0;

我猜这是因为我不能从类外部初始化一个私有成员。那么最好的方法是什么呢?


当前回答

我只是想提一下我第一次遇到这个的时候觉得有点奇怪的东西。

我需要在模板类中初始化一个私有静态数据成员。

在.h或.hpp中,它看起来像这样初始化模板类的静态数据成员:

template<typename T>
Type ClassName<T>::dataMemberName = initialValue;

其他回答

使用Microsoft编译器[1],不像int型的静态变量也可以在头文件中定义,但在类声明之外,使用Microsoft特定的__declspec(selectany)。

class A
{
    static B b;
}

__declspec(selectany) A::b;

请注意,我并不是说这是好的,我只是说这是可以做到的。

现在,比MSC更多的编译器支持__declspec(selectany)——至少gcc和clang。甚至更多。

类声明应该在头文件中(如果不共享,则在源文件中)。 文件: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;
};

对于变量:

foo。:

class foo
{
private:
    static int i;
};

foo.cpp:

int foo::i = 0;

这是因为在你的程序中只能有一个foo::i实例。它相当于头文件中的extern int i和源文件中的int i。

对于常量,你可以把值直接放在类声明中:

class foo
{
private:
    static int i;
    const static int a = 42;
};

也在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

这符合你的目的吗?

//header file

struct MyStruct {
public:
    const std::unordered_map<std::string, uint32_t> str_to_int{
        { "a", 1 },
        { "b", 2 },
        ...
        { "z", 26 }
    };
    const std::unordered_map<int , std::string> int_to_str{
        { 1, "a" },
        { 2, "b" },
        ...
        { 26, "z" }
    };
    std::string some_string = "justanotherstring";  
    uint32_t some_int = 42;

    static MyStruct & Singleton() {
        static MyStruct instance;
        return instance;
    }
private:
    MyStruct() {};
};

//Usage in cpp file
int main(){
    std::cout<<MyStruct::Singleton().some_string<<std::endl;
    std::cout<<MyStruct::Singleton().some_int<<std::endl;
    return 0;
}