在C++中,直接(direct)和间接(copy)初始化对象有所不同:
直接初始化:
MyClass obj(arg1, arg2); int x(5);
对于类,直接调用合适的构造函数。
间接初始化:
MyClass obj = MyClass(arg1, arg2); int x = 5;
这会创建一个临时对象,然后复制(或移动)它(使用复制或移动构造函数)。
区别:
示例:
struct NonCopyable { NonCopyable(int) {} NonCopyable(const NonCopyable&) = delete; }; NonCopyable a(5); // OK: 直接 NonCopyable b = NonCopyable(5); // OK, 优化情况下,C++17之前出错 NonCopyable c = 5; // 错误: 没有复制构造函数
"如果使用C++11并启用优化编译器,copy-initialization是否可能导致比direct-initialization更多的构造函数调用?"
答案: 理论上是的。如果没有复制消除,copy-initialization创建临时对象,然后调用复制或移动构造函数。Direct-initialization始终只调用主构造函数。然而,现代编译器在启用优化时(C++17及以上)通过保证复制消除消除了这一区别。
故事
在一个金融项目中使用了带有临时对象的copy-initialization,但所需类型没有复制构造函数。应用程序在旧编译器上(C++17之前)无法编译,尽管direct-init工作正常。
故事
在数据序列化工具中,程序员认为direct-init和copy-init是等效的。结果导致了大量结构的多余复制和性能下降。
故事
在初始化用户对象的全局数组时,使用了间接初始化。错误只在一个平台上显现,该平台未进行复制消除,并且由于ABI的特性而产生了隐式调用多余的构造函数。