【C++】只允许一次类类型隐式转换,字符串字面量并不是string类型

本文分析了C++中涉及构造函数和隐式转换的代码错误,解释了字符串字面值不能直接传递给接受string参数的函数的原因。主要讨论了字符串字面值与string类型的差异,以及编译器对于隐式转换的限制。通过示例展示了如何通过显式转换解决此问题,并强调了理解类型转换在编程中的重要性。
摘要由CSDN通过智能技术生成
class Demo{
public:
    Demo() {}
    Demo(const string& tt) {
        cout << "abc";
    }
};

void func(Demo a) {
    cout << "aaa";
}

void main(){
	func("aaa");
}

在这里插入图片描述
显示上图中的错误,首先我们分析一下这个代码。

每个类都分别定义了它的对象被初始化的方式,类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。如果构造函数只接受一个参数,且这个参数不是该类的对象引用,则它实际上定义了转换为此类型的隐式转换机制,一般称之为转换构造函数。所以代码中以string为形参的构造函数就是一条string转换为Demo类型的转换构造函数。

string str = "aaa";
func(str);

如果我们先定义一个string变量,然后将这个变量传递给func。首先发生的是string->Demo类型的转换,然后作为函数实参传递给参数。这是可行的。

func(“aaa”);			//报错
func(string(“aaa”));	//可行

为什么将字符串显示地转换成string,就允许充当func函数的参数,而字符串本身不允许。

为了解决这个问题,我们首先查阅一下字符串字面值到底是什么?

因为某些历史原因,也为了与C兼容,所以C++语言的字符串字面值并不是标准库类型string对象。切记,字符串字面值与string是不同的类型。字符串字面值的类型实际上是由常量字符构成的数组。

所以前面我们看到的“aaa”并不是string类型,而是字符数组类型。如果要将“aaa”作为func函数参数,首先要进行第一步就是将字符串字面值转换为string对象。标准库允许把字符串字面值转换成string对象。

Demo demo("aaa");		//正确

所以上述代码是正确的。Demo类本身并没有接收字符串字面值的转换构造函数,但是有针对string的转换构造函数,所以这里面发生了一次隐式转换,将字符串字面值转换为string,然后调用string转换构造函数。

func(“aaa”);			//报错

那为什么这里会报错,不是可以发生隐式转换吗?

这里报错涉及到编译器另外一条规则。

类类型能定义由编译器自动执行的转换,不过编译器每次只能执行一种类类型的隐式转换。如果同时提出多个转换请求,编译器会报错。

字符串字面量转换为string属于标准库的类类型转换,区别于普通变量类型转换。这里发生了两次转换,第一次是字符串字面值转换为string,第二次是string转换为Demo类型。因此报错。

func(string(“aaa”));	//可行

那为什么这条代码可以?

因为第一次的字符串字面值转换为string是显式转换,编译器只需要完成一次string转换为Demo类,没有超过一次。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值