问题 在C ++头中声明和定义静态变量?


许多  其他  问题 处理如何通过在头文件中声明变量并在.cpp文件中定义(分配)来分配变量。

我想要做的是不为我的类使用任何.cpp文件,并将所有函数定义为内联(在头文件中)。我遇到的问题是如何定义静态成员变量,以便即使.h文件包含在多个编译单元中,我也不会得到“此处首次定义”链接器错误。

如果它完成了工作,我对预处理器黑客等开放。我只是想避免任何.cpp文件。

如果重要我正在使用GCC。


1702
2017-08-03 10:28


起源

您只需将变量声明为 static。将在包含头文件的每个转换单元中创建一个新的变量实例,但在链接时,由于对象具有静态链接,因此不会发生冲突...
不,静态数据成员具有外部链接。 - jrok
“定义它(分配)”: 确定 和 分配 是两件不同的事情。 - Pete Becker
@cmaster - 分配是 部分 定义,但它们不是一回事。 - Pete Becker
@PeteBecker确实这些单词具有不同的含义,但是,对于变量,它们本质上是同义词,因此“定义它(分配)”没有任何问题。但是这个讨论没有任何结果,所以我建议我们都删除我们的评论。 - cmaster


答案:


如果你真的必须避免任何.cpp文件,你可以滥用单例模式:

class Foo {
    public:
        static Bar& getMyStatic() {
            static Bar bar;
            return bar;
        };
};

这是有效的,因为现在变量是函数内部的静态变量 static 在函数上下文中具有与在类上下文中不同的含义。对于函数,链接器确实识别多个相同的定义并丢弃副本。

但是,当然,我强烈建议不要避免使用.cpp文件:这意味着你需要在一个大块中构建整个程序或至少大部分程序。您所做的每一项更改都需要完全重建,这会显着减慢您的更改 - 编译 - 测试周期。对于可能不是问题的非常小的项目,但它适用于中型到大型项目。


14
2017-08-03 11:34



这似乎是避免将静态变量放在.cpp文件中的最佳(也是唯一)方法。至于编译时间:我编译的代码限制为32KB,因此它将花费多长时间。 - srlm


对于静态变量,您必须放入.cpp文件,以避免在意图只有一个静态变量的情况下出现多个静态变量。除此之外,使用大型内联方法并不是一个好主意,因为它只是对编译器的一个提示,但也使编译需要更长时间(您在开发中更改了一些这些函数,然后需要编译许多相关文件!)

但是,如果你不想要很多只带有一些静态的.cpp文件,为什么不用一个文件来存储它们。


0
2017-08-03 10:35





只要您在整个项目中只包含该头文件一次,您就可以了。然而,这是一个非常强烈的要求,并且很难让其他人坚持。

你可以有一个 static 变量,但这意味着你有一个以上的整个程序,这可能会或可能不重要(请记住,你将来不能改变它,所以你可能有一个所谓的“潜在的bug” - 你更改其他一些代码,突然之间你创建了一个新的bug,因为变量不是一个变量)。


-1
2017-08-03 10:34



麻烦的是,它可能不会重要,但它将来可能会做,而你无意中引入了一个错误 - Ed Heal
当然,这是一个好点。 - Mats Petersson