c++ - 隐式类类型转换是否使用复制构造函数?

标签 c++ copy-constructor implicit-conversion copy-elision copy-initialization

以下引用 self 的 C++ 书籍:

When we use direct initialization, we are asking the compiler to use ordinary function matching to select the constructor that best matches the arguments we provide. When we use copy initialization, we are asking the compiler to copy the right-hand operand into the object being created, converting that operand if necessary.

对我来说,这个加粗的部分会产生一些歧义。这听起来像是将右手操作数转换为类类型,然后使用复制构造函数,例如;

string s = "hello";

会变成...

string s = string("hello"); 

它使用复制构造函数。如果这是真的那么我的测试程序;

#include <iostream>
using namespace std;

class A{
public:
    A(const A& b): data(b.data) { cout << "The first way" << endl;}
    A(const char* c): data(c) { cout << "The second way" << endl;}
    string data;

};
int main(){
    A first("hello");
    A second = "sup";
}

应该产生“第二种方式,第二种方式,第一种方式”。但是它会打印“第二种方式,第二种方式”。由此我可以得出结论,它使用的是 const char* 构造函数而不是复制构造函数。我会接受这个,除非稍后它说......

During copy initialization, the compiler is permitted (but not obligated) to skip the copy/move constructor and create the object directly. That is, the compiler is permitted to rewrite

string null_book = "9-999-99999-9"; 

into

string null_book("9-999-99999-9");

However, even if the compiler omits the call to the copy/move constructor, the copy/move constructor must exist and must be accessible (e.g., not private) at that point in the program.

我不确定为什么复制构造函数甚至需要在这些示例中提及,不是

 string null_book = "9-999-99999-9"

总是隐含地意味着 const char* 构造函数无论如何都在使用?事实上,为了使上述工作正常,需要定义复制构造函数对我来说意义不大。但是,可惜,如果我将“const A&”构造函数设为私有(private)(其余为公共(public)),那么我的程序将无法运行。为什么必须为甚至不涉及它的隐式转换定义复制构造函数? "string null_book = "9-999-99999-9""使用什么构造函数?

最佳答案

string null_book = "9-999-99999-9";表示 string null_book = string("9-999-99999-9"); .

这使用了 const char * constructor 构造一个临时对象,然后 null_book从临时对象复制/移动构造,然后临时对象被销毁。

(复制/移动构造意味着如果可用则使用移动构造函数;否则使用复制构造函数)。

然而,这种情况也符合复制省略的条件。您实际上在问题中引用了复制省略规范,因此我不再重复。

编译器可能会选择为两个null_book 使用相同的内存空间。和临时对象,并省略对临时对象析构函数和 null_book 的调用复制/移动构造函数。

在您的情况下,编译器确实选择这样做,这就是您看不到任何复制构造函数输出的原因。

一些编译器允许通过开关禁用复制省略,例如gcc/铛 -fno-elide-constructors .

More info about copy elision

关于c++ - 隐式类类型转换是否使用复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32215501/

相关文章:

c++ - 在 Qt3D 中禁用抗锯齿

c++ - OpenMP 中的并行合并排序

C++ 虚拟基类 : parent's copy constructor doesn't get called

c++ - 从指针或指针链(对象指针、模板)复制数据

c++/openframeworks - 如何在开放框架程序之间切换

c++ - 有什么办法可以帮助代码返回值是 const 引用吗?

c++ - 复制构造函数不被继承

C++11 隐式转换

javascript - 为什么 JavaScript 坚持将 float 转换为整数?

c++ - 为什么在调用隐式类型转换构造函数后直接是析构函数?