栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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类,没有超过一次。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019272.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号