C++ 类的隐式转换

所谓类的隐式转换,就是将实参类型转成形参类型--如果不一致的话。

这个转换与基本类型转换不太一样,具体则是在形参类型的构造函数中使用实参类型的数据,从而构造出一个临时对象

下面的代码,类Person 的成员函数 isSamePerson(const Person &person) const ,理论上需要一个 Person 引用,但实际上被传递了一个 string对象

编译器会自动调用 Person tmp(str)构造函数 来构造一个临时对象,而不是真的将 string类型 转成 Person 类型!

代码:

#include <iostream>
#include <string>

using namespace std;

class Person{
    private:
        string name;
        int id;
        
    public:
        Person(const string &nm=string("xxx")):name(nm),id(0){} //就不用默认无参构造了 ;隐式转换
        
    public:
        bool isSamePerson (const Person &person) const{ //const成员函数 ,只能调用const成员(变量、函数)!
            cout<<"比较对象:"<<person.getId()<<"--"<<person.getName()<<endl;//
            return id == person.getId(); //
        }
        
        const int &getId() const{ //任意一个const去掉后,都会导致问题。。。 
            return id;
        }
        const string &getName() const{ //因为const修饰的是this指向的对象,所以也必须返回const引用
            return name;
        }
};

int main(){
    string a="aaa";
    Person p1(a);
    cout<<p1.getId()<<"--"<<p1.getName()<<endl;
    
    string b="bbb";
    cout<<p1.isSamePerson(b)<<endl; //隐式转换!!! 
    
    return 0;
}

尽管有时候这样的转换是我们需要的,但也有不需要的时候,这个时候,给类中的构造函数声明加上explicit,则会防止在需要隐式转换的上下文中使用该构造函数。

#include <iostream>
#include <string>

using namespace std;

class Person{
    private:
        string name;
        int id;
        
    public:
        explicit Person(const string &nm=string("xxx")):name(nm),id(0){} //就不用默认无参构造了 ;显式 explicit
        
    public:
        bool isSamePerson (const Person &person) const{ //const成员函数 
            cout<<"比较对象:"<<person.getId()<<"--"<<person.getName()<<endl;//
            return id == person.getId(); //
        }
        
        const int &getId() const{ //任意一个const去掉后,都会导致问题。。。 
            return id;
        }
        const string &getName() const{ //因为const修饰的是this指向的对象,所以也必须返回const引用 
            return name;
        }
};

int main(){
    string a="aaa";
    Person p1(a);
    cout<<p1.getId()<<"--"<<p1.getName()<<endl;
    
    string b="bbb";
    cout<<p1.isSamePerson(Person(b))<<endl;//显式转换!!! 
    
    return 0;
}
 
结论:除非有明显的理由想要使用隐式转换,否则,单形参的构造函数应该设置为explicit
 
 
其他前向声明只能用于使用指针引用的情况。
原文地址:https://www.cnblogs.com/larryzeal/p/5613870.html