如何正确使用转换构造函数

How to correctly use converting constructors?

本文关键字:转换 构造函数 何正确      更新时间:2023-10-16

我读到C++编译器能够在提供合适的转换构造函数或操作数时隐式转换类型。事实上,我发现了看起来很像这样的示例代码:

class Dog{
private:
string name;
public:
Dog(string n):name(n){} //This as the converting constructor
}
int main(){
Dog d = "rover";
}

每当我运行此代码时,编译器都会抛出一条错误消息:

请求从"const char[6]"到非标量类型"Dog"的转换Dog d="漫游者";

编译时,我添加了编译器选项-std=c++11,所以它不应该是关于C++版本的,对吧
我在网上找到的例子(至少对我来说)看起来完全一样,所以我不知道这里出了什么问题
例如,我对此主题的投入来自于此视频:转换构造函数和重载运算符-新的moston

您还需要了解您使用的是复制初始化,而不是

直接初始化他们是不同的,你需要了解他们是如何做到的,以及他们与explicit的关系。您需要了解转换链是如何工作的,其中最多涉及一个用户定义的转换。

Dog d1 ("rover");
Dog d2 = "rover";

d2大小写尝试将文字转换为Dog,然后将其复制(移动)到d2。但这将是双重转换:const char*string,然后stringDog

d1大小写构造d1,将参数传递给构造函数,因此只有一次转换const char*string。(在这两种情况下,将const char [6]提升为const char*也在其中,但不计入允许的"唯一一个",属于不同的类别。)

复制初始化没有指定"漫游者"作为构造函数的参数。上面写着"这里有些东西,但这里需要一个Dog">这里是复制init声明语法的右侧,而不是任何可识别的函数。编译器必须找到合法的转换。

在直接初始化的情况下,只是为函数(构造函数)提供参数。编译器将您提供的内容转换为声明的参数类型。

注意,"rover"不是std::string,而是const char[6](末尾有空字符)(可能衰减为const char*),要使Dog d = "rover";工作,需要将"rover"转换为std::string,然后再转换为Dog

但用户定义的转换不会在一次隐式转换中被考虑两次。

(重点矿井)

在隐式转换的第二阶段调用用户定义的转换函数,隐式转换由零个或一个转换构造函数或零或一个用户定义的转化函数组成。

您可以显式地将"rover"转换为std::string以使其工作。

Dog d = std::string("rover");

您需要另一个构造函数,它允许您从const char*:进行构造

Dog(const char* n):name(n){}

请记住,"rover"不是std::string,类型不会被推导为隐式使用转换构造函数。正如@songyuanyao在他们的回答中提到的那样,转换只会进行一次。

另一种选择是写入:

Dog d = std::string("rover");