C++ 类的隐式转换

Posted LarryZeal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
 
 
其他前向声明只能用于使用指针引用的情况。

 

以上是关于C++ 类的隐式转换的主要内容,如果未能解决你的问题,请参考以下文章

c++ 隐式声明是啥意思

两个类(C++)中的类到类转换 - 前向声明?

Scala中的隐式转换|理解

深入浅出JavaScript中的隐式转换

UnityEngine.Object类的隐式bool转换,何时为null问题。

C++ 函数到指针的隐式转换:哪个编译器是正确的? Clang 和 GCC 不同意