你能阻止构建未使用的静态对象吗?

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)

wal*_*nut 5

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

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

但这并不意味着,如果静态成员(odr-) 使用,则初始化程序仅在程序运行中第一次使用该变量时才运行。是否是这种情况是实现定义的。


在程序代码中不使用变量时,不仅保证初始化程序永远不会运行,而且保证它在第一次使用时准确运行的替代方法是staticstatic成员函数中使用局部变量反而:

static const Bar& constVar() {
    static const Bar instance(1);
    return instance;
};
Run Code Online (Sandbox Code Playgroud)

然后使用它constVar()代替constVar. (函数的定义也可以是类外的。)但是这会带来性能损失,因为局部静态的实现必须是线程安全的。

  • 请小心静态本地成员 - 这种便利是以每次调用的额外标志和 *mutex* 锁定/解锁为代价的(根据 C++ 标准要求静态本地初始化必须是线程安全的)。 (2认同)