你能阻止未使用的静态 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 编辑到您的可执行文件或共享库中。
当我 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 编辑到您的可执行文件或共享库中。