仅在非静态的情况下构造
Only construct if non-static
我有一个侵入式链表,它在各种上下文中使用——有时被用作全局静态变量,有时被用作普通变量。
当它被用作全局静态变量时,我希望我能避免运行构造函数,因为所有成员都将初始化为零。
当它被用作普通变量时,我希望有一个构造函数来初始化null
的成员(两个指针)。
这样做的动机是我有不同的编译单元,并且不能控制调用静态构造函数的顺序。其他编译单元中的一些构造函数正在"挂接"到全局列表中,问题是一个构造函数可能会在构造列表之前使用该列表。
当时的想法是,如果不需要构建列表,那么初始化顺序就没有问题。
只需正常编写默认构造函数,但将其设为constexpr
。
struct List
{
constexpr List() : head(nullptr), tail(nullptr) { }
...
};
当您定义一个具有静态存储持续时间(即全局)的List
对象时,编译器会确保该对象不是动态初始化的,因此在动态初始化阶段,它保证在任何其他构造函数需要它之前发生。
当您声明一个具有自动或动态存储持续时间的变量(即作为本地变量或在堆上)时,构造函数将正常运行并设置两个成员。
这正是像std::mutex
这样的类型具有constexpr构造函数的原因,以确保在任何事情都可以尝试使用它们之前对它们进行初始化。
如果您需要C++03解决方案,请将全局设置为本地静态,可以根据需要通过以下函数访问(并初始化):
inline List& global_list()
{
static List list;
return list;
}
或者你可以求助于一个涉及第二个构造函数的笨拙解决方案:
struct List
{
struct no_init_t { };
static no_init_t no_init;
List() : head(0), tail(0) { }
List(no_init_t) { }
...
};
List global_list(List::no_init);
第二个构造函数有意不进行初始化,因为全局的成员最初都是零。这意味着,如果另一个翻译单元中的代码在列表的生存期开始之前访问该列表(这在技术上是未定义的行为),它会找到零值的成员,并可以添加到列表中,如果no_init
列表构造函数稍后运行,它不会将变量清零,也不会丢失之前添加的数据。这很难看,但应该有效。显然,no_init
构造函数应该只用于全局,所以这个解决方案更容易出错。
- 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- 如何在没有实例的情况下获取非静态方法的类型?
- 如何在不使用静态矩形方法的情况下创建 IDOMPathGeometryPtr?
- C++ - 如何在不静态的情况下将回调绑定到类方法?
- 在这种情况下,我们可以使用静态而不是朋友吗,还有其他解决方案是什么
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- 在不中断引用的情况下移动静态库的 *.pdb 文件 - LNK4099
- 在没有显式作用域的情况下无法访问模板基类的静态成员
- C :在没有对象实例的情况下调用非静态成员函数
- 在不指定实例化的情况下调用类模板的静态方法的方法
- 默认情况下,使 std 的数据结构使用我现有的非静态哈希函数"hashCode()"
- C 在不构造它的情况下创建静态对象(无需分配)
- 递归计算在不使用静态局部变量,全局变量或静态函数的情况下,在递归函数中发生的环数
- 在没有对象参数编译器错误的情况下调用非静态成员函数
- 在某些情况下,如何理解允许实现将非局部变量的动态初始化视为静态初始化
- Eclipse CDT:如何在没有项目清理>>项目重建的情况下重新链接静态库
- 在没有全局或静态变量的情况下配置Bison和Flex
- 如何在不使用静态变量的情况下从递归函数中只调用另一个函数一次
- 仅在非静态的情况下构造
- 在依赖的情况下静态初始化