C++中的explicit关键字

发布时间 2023-12-20 11:50:24作者: Hello-World3

一、简介

explicit关键字可以阻止隐式转换的发生。

举例:
C++中只带有一个参数的构造函数,或者或者除了第一个参数外其余参数都有缺省值的多参构造函数,承担了两个角色:

(1) 用于构建单参数的类对象。
(2)隐含的类型转换操作符。

一个类A的构造函数 A(int i) 就是既可以用来作为构造器,又可以实现隐式转换 A a=1;因为1可以通过构造函数 A(int i) 转换为一个类A的对象,这就提现了隐含类型转换操作。


二、例子

1. 不使用explicit

#include <iostream>
using namespace std;
  
class Complex {
private:
    double real;
    double imag;
  
public:
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i)
    {
        cout << "Complex(" << r << ", " << i << ")" << endl;
    }

    bool operator==(Complex rhs)
    {
        cout << "operator==() rhs.real=" << rhs.real << " rhs.imag=" << rhs.imag << endl;
        return (real == rhs.real && imag == rhs.imag) ? true : false;
    }
};

int main()
{
    // a Complex object
    Complex com1(3.3, 4.4);
  
    if (com1 == 5.5)
        cout << "Same" << endl;
    else
        cout << "Not Same" << endl;

    return 0;
}

/*
~/tmp/5.cpp_test/2.explicit$ g++ explicit_test.cpp -o pp
~/tmp/5.cpp_test/2.explicit$ ./pp
Complex(3.3, 4.4)
Complex(5.5, 0)
operator==() rhs.real=5.5 rhs.imag=0
Not Same
*/

可以看到在进行赋值时,Complex构造函数调用了一次,先把5.5隐式转换为Complex类对象,然后再调用operator==()进行比较。


2. 使用explicit

#include <iostream>
using namespace std;
  
class Complex {
private:
    double real;
    double imag;
  
public:
    explicit Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) //注明需要显式调用
    {
        cout << "Complex(" << r << ", " << i << ")" << endl;
    }

    bool operator==(Complex rhs)
    {
        cout << "operator==() rhs.real=" << rhs.real << " rhs.imag=" << rhs.imag << endl;
        return (real == rhs.real && imag == rhs.imag) ? true : false;
    }
};

int main()
{
    // a Complex object
    Complex com1(3.3, 4.4); //显式调用构造函数
    Complex com2 = 6;
  
    if (com1 == (Complex)5.5) //显式类类型转换
        cout << "Same" << endl;
    else
        cout << "Not Same" << endl;

    return 0;
}

/*
~/tmp/5.cpp_test/2.explicit$ ./pp
Complex(3.3, 4.4)
Complex(5.5, 0)
operator==() rhs.real=5.5 rhs.imag=0
Not Same
*/

加了 explicit 禁止了隐式类型转换,这种情况继续使用就会报错。可改为显式类型转换后继续使用。