c++隐式的类类型转换

先看代码

#include <iostream>
#include <string>
using namespace std;
class Student
{
    string name;
    int number;
public:
    Student(const string &str, int n = 1) : name(str), number(n) {} 
    Student() {}
    void Print(const Student &s); //期待的是Student类的参数
};
void Student::Print(const Student &s)
{
    if (s.name == name) 
    {
        cout << "same person" << endl;
    }
    else 
    {
        cout << "different" << endl;
    }
}
int main()
{
    Student a("lzj");
    Student b("lb");

    cout << "a == b ? : " <<endl;
    a.Print(b);

    cout << "a == a ? : " << endl;
    a.Print(string("lzj")); //这里传递的是string类

    // cout << "a == a ? : " << a.Print("lzj") << endl;
    return 0;
}

输出结果为

a == b ? :
different
a == a ? :
same person

为什么呢? 明明第二个传递的是一个string类的参数,结果却是same
这是因为c++里,能通过一个实参调用的构造函数定义了一条从构造函数的参数类型向类类型隐式转换的规则(c++ primer P296)
也就是说,string类的实参被隐式转换成了Student类类型,而当上面的构造函数里的参数列表里,不去默认给n赋初值的话,必须传递两个实参的时候,也就不成立了
同时,编译器只允许一步类类型转换,意思也就是说,只会自动执行一步类型转换,其实当我们创建对象时,传递进去的“lzj”和“lb”都被隐式的从const char 转换成了string类,所以,被我注释掉的那条语句编译不会通过,因为只能一步的从const char 转换为string,而不能再次转换为类类型了

如何阻止:可以将构造函数声明为explicit加以阻止,此时没有任何构造函数可以隐式的创建类对象,explicit只对一个实参的构造函数有效,需要多个实参的构造函数不能用于执行隐式转换,无须指定为explicit。只能在类内声明构造函数时使用explicit,类外部定义时不应重复
而且,explicit构造函数只能用于直接初始化,不能用于拷贝形式的初始化过程。声明为explicit后,编译器将不会在自动转换过程中使用该构造函数,但是,虽然编译器不会将其使用于隐式转换过程,但我们仍然可以使用这样的构造函数显示的强制转换

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值