explicit关键字的作用
explicit关键字在写程序时使用的次数较少,但是仔细观察会发现,在C 标准库中的相关类声明中explicit出现的频率是很高的,那么explicit关键字到底有什么作用呢?接下来我就为大家一一解答。
explicit为清晰的;明确的之意.顾名思义,关键字explicit可以阻止隐式转换的发生。
例如: C 中只带有一个参数的构造函数,或者或者除了第一个参数外其余参数都有缺省值的多参构造函数,承担了两个角色:
1.用于构建单参数的类对象。
2.隐含的类型转换操作符。
例如:一个类A的构造函数A(int i)就是,既可以用来作为构造器,又可以实现隐式转换A a=1;因为1可以通过构造函数A(int i)转换为一个类A的对象。(隐含的类型转换操作符)
但有时我们并不想让他进行隐式类型转换,这时C 的explicit关键字就起到作用了。
注意:当类的声明和定义分别在两个文件中时,explicit只能写在在声明中,不能写在定义中。
下面我将为大家介绍三种使用explicit关键字的情况:
类型转换函数
#includeusing namespace std;class Fraction{public: Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){} operator double() const{ return (double)m_numerator/m_denominator; }private: int m_numerator; int m_denominator;}
int main(void){ Fraction fraction(3, 5); double d = 3.5 f; cout << d << endl; return 0;}
我们设计了一个Fraction类(分数类), 在主函数中定义了一个分数对象f,然后将3.5 f赋值给double类型变量d, 但是我们发现f并不是一个double类型的变量,因此编译器会从Fraction类中寻找operator double()函数,隐式调用该函数将Fraction类型转换成一个double类型. operator double()就是我们所说的类型转换函数(type conversion function)。
类型转换函数的一般形式
operator 数据类型 const()
{//函数实现}
1.转换函数必须是类的成员函数
2.转换函数不能声明返回类型
3.形参列表必须为空
4.类型转换函数通常应该是const
当我们想要在明确声明类型转换的时候,才使用类型转化函数时,这时我们就需要使用到explicit关键字了.使用方法如下:
#includeusing namespace std;class Fraction{public: Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){} explicit operator double() const{ return (double)m_numerator/m_denominator; }private: int m_numerator; int m_denominator;}
int main(void){ Fraction fraction(3, 5); double d = 3.5 static_cast<double>(f); cout << d << endl; return 0;}
注意,这时当我们想调用类型转换函数的时候,需要写成static_cast(f);
注意static_cast 是C 11 引入的类型转换运算符。
单操作数构造函数
还是采用上面的Fraction类,这次我们重载(overload) “ ” 号运算符,使得仍然可以达到相同的效果。
#include
using namespace std
class Fraction
{
public: Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){} double operator (const Fraction& a) { return (a.m_numerator this->m_numerator)/(a.denominator this->m_denominator); }
private:int m_numerator;
int m_denominator;} int main(void){ Fraction fraction(3, 5); double d = f 3; cout << d << endl; return 0;
}
在double d = f 3 这句话中构造函数就是前面所提到的第二种角色隐含的类型转换操作符。因为执行到这句话首先会调用 的重载函数,该函数的调用对象默认为左操作数,右操作数为Fraction类型,因此会调用构造函数将3转换成Fraction类型,然后将得到的返回值double类型赋值给变量d。
同理如果不想让构造函数进行隐式类型转换,可以在构造函数前面加上explicit关键字,防止进行隐式转换.使用方法如下:
#include
using namespace std
class Fraction
{
public:explicit Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){} double operator (const Fraction& a) { return (a.m_numerator this->m_numerator)/(a.denominator this->m_denominator); }private: int m_numerator; int m_denominator; } int main(void){ Fraction fraction(3, 5); double d = f 3; cout << d << endl; return 0;}
你可能会注意到,加上explicit 关键字之后,这个代码将不能正确执行。
来源:code_campaignblog.csdn.net/l2563898960/article/details/97769569