如何在C ++中初始化私有静态成员?

让人想犯罪 __ 提交于 2020-02-28 00:51:10

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

class foo
{
    private:
        static int i;
};

int foo::i = 0;

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


#1楼

对于以后这个问题的观众,我想指出,您应该避免monkey0506的建议

头文件用于声明。

头文件将针对每个直接或间接#includes .cpp文件进行一次.cpp ,并且任何函数之外的代码都将在程序初始化时运行在main()之前。

通过输入: foo::i = VALUE; 在头文件中, foo:i将为每个.cpp文件分配值VALUE (无论是什么),并且这些分配将在运行main()之前以不确定的顺序(由链接器确定main()进行。

如果我们在其中一个.cpp文件中#define VALUE为其他数字怎么办? 它将编译良好,并且在运行程序之前,我们将无法知道哪一个获胜。

绝对不要将执行的代码放入标头中,原因与您从未#include .cpp文件相同。

包含卫士(我同意您应该始终使用)来保护您免受不同的伤害:同一头文件在编译单个.cpp文件时多次间接#include d


#2楼

如果使用标题防护,也可以将分配包括在标题文件中。 我将这种技术用于我创建的C ++库。 获得相同结果的另一种方法是使用静态方法。 例如...

class Foo
   {
   public:
     int GetMyStatic() const
     {
       return *MyStatic();
     }

   private:
     static int* MyStatic()
     {
       static int mStatic = 0;
       return &mStatic;
     }
   }

上面的代码具有不需要CPP /源文件的“好处”。 同样,这是我用于C ++库的一种方法。


#3楼

类声明应该在头文件中(如果未共享,则在源文件中)。
档案:foo.h

class foo
{
    private:
        static int i;
};

但是初始化应该在源文件中。
档案:foo.cpp

int foo::i = 0;

如果初始化在头文件中,则每个包含头文件的文件都将具有静态成员的定义。 因此,在链接阶段,您将得到链接器错误,因为初始化变量的代码将在多个源文件中定义。 static int i的初始化必须在任何函数之外完成。

注意: Matt Curtis:指出,如果静态成员变量为const int类型(例如intboolchar ),则C ++允许简化上述操作。 然后,您可以直接在头文件的类声明中声明和初始化成员变量:

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

#4楼

对于变量

foo.h:

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;
};

#5楼

int foo::i = 0; 

是用于初始化变量的正确语法,但是它必须位于源文件(.cpp)中,而不是标头中。

因为它是一个静态变量,所以编译器仅需要创建一个副本。 您必须在代码中的某些位置插入“ int foo:i”行,以告诉编译器将其放置在何处,否则会出现链接错误。 如果在标头中,则将在每个包含标头的文件中获得一个副本,因此请从链接器获取多个已定义的符号错误。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!