Arc*_*uke 0 c++ linker static g++ build
当我链接一个包含静态对象的文件时,无论是否使用过该对象或者是否包含标头,都会运行该对象的构造函数。g++ 中有没有办法阻止这种行为的发生,或者是不链接文件的唯一答案?
foo.h
#include <iostream>
class Bar {
public:
Bar(int inMemberInt) {
std::cout << "In Bar constructor." << std::endl;
}
};
class Foo {
public:
static const Bar constVar;
};
Run Code Online (Sandbox Code Playgroud)
文件
#include "foo.h"
const Bar Foo::constVar(1);
Run Code Online (Sandbox Code Playgroud)
主程序
#include <iostream>
int main() {
std::cout << "Hello." << std::endl;
return 1;
}
Run Code Online (Sandbox Code Playgroud)
构建命令
g++ foo.h foo.cpp main.cpp -o main
Run Code Online (Sandbox Code Playgroud)
输出
In Bar constructor.
Hello.
Run Code Online (Sandbox Code Playgroud)
您可以将类设为模板(可能带有默认模板参数),然后静态数据成员的定义仅在程序中的某处使用 (odr-) 时才会实例化。
不过,这需要您将类成员的定义移动到标题中。如果这影响太大,您可能需要考虑将静态成员放在作为类模板的基类中,这与使整个类成为模板的效果相同,只要您不引用任何地方的静态成员。在任何情况下都需要将静态成员的定义移动到标题中(显式实例化会抵消预期的效果。)
但这并不意味着,如果静态成员被(odr-) 使用,则初始化程序仅在程序运行中第一次使用该变量时才运行。是否是这种情况是实现定义的。
在程序代码中不使用变量时,不仅保证初始化程序永远不会运行,而且保证它在第一次使用时准确运行的替代方法是static在static成员函数中使用局部变量反而:
static const Bar& constVar() {
static const Bar instance(1);
return instance;
};
Run Code Online (Sandbox Code Playgroud)
然后使用它constVar()代替constVar. (函数的定义也可以是类外的。)但是这会带来性能损失,因为局部静态的实现必须是线程安全的。