你能阻止未使用的静态 objects 被构造吗?

Can you stop unused static objects from being constructed?

当我 link 一个包含静态 object 的文件时,无论 object 是否曾经存在,object 的构造函数都是 运行使用或 header 甚至包括在内。 g++ 中有没有一种方法可以阻止这种行为的发生,或者是不 link 文件的唯一答案?

foo.h

#include <iostream>

class Bar {
public:
    Bar(int inMemberInt) {
        std::cout << "In Bar constructor." << std::endl;
    }
};

class Foo {
public:
    static const Bar constVar;
};

foo.cpp

#include "foo.h"

const Bar Foo::constVar(1);

main.cpp

#include <iostream>

int main() {
    std::cout << "Hello." << std::endl; 

    return 1;
}

构建命令

g++ foo.h foo.cpp main.cpp -o main

输出

In Bar constructor.
Hello.

您可以将 class 设为模板(可能使用默认模板参数),然后静态数据成员的定义将仅在程序中某处使用 (odr-) 时实例化。

不过,这需要您将 class 成员的定义移动到 header 中。如果这影响太大,您可能需要考虑将静态成员放在作为 class 模板的基础 class 中,这与使整个 class 一个模板,只要你不在任何地方引用静态成员。在任何情况下,静态成员的定义都需要移至 header(显式实例化会抵消预期效果。)

这并不意味着,如果静态成员 (odr-) 使用,初始化程序将 运行 只有当变量第一次被使用时节目时间 运行。是不是这样implementation-defined。


替代方案不仅保证在程序代码中未使用变量时初始化程序永远不会 运行,而且保证它在使用时恰好是 运行第一次,是在 static 成员函数中使用局部 static 变量:

static const Bar& constVar() {
    static const Bar instance(1);
    return instance;
};

然后将其用作 constVar() 而不是 constVar。 (函数的定义也可以是 out-of-class。)然而,这确实会带来性能损失,因为局部静态的实现必须是 thread-safe.

另一种选择是在其自己的源文件中定义静态对象。然后将该源文件编译成目标文件,并将 link 与其他目标文件(如果有)一起编译成静态库 (.a)。当针对静态库 linking 您的可执行文件(或共享库)时,linker 仅包含静态库中解析任何未解析符号的那些 .o 文件。因此,如果没有任何内容引用该静态对象,则定义它的对象文件不会 link 编辑到您的可执行文件或共享库中。