C++中的explicit关键字只能用于修饰一个只有一个参数的类构造函数,它的作用是表明该构造函数是显示的,而非隐式的,跟它相对应的另一个关键字是implicit,意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。
explicit关键字的作用:禁止隐式调用类内的单参数构造函数,主要包括如下三层意思:
(1)该关键字只能用来修饰类内部的构造函数
(2)禁止隐式调用拷贝构造函数
(3)禁止类对象之间的隐式转换
non-explicit-one-argument ctor
我们在用C++实现分数的时候,除了可以用conversion function转换函数将Fraction对象转换成double型(分子除以分母),还可以用non-explicit-one-argument ctor函数,只有一个实参的非明确函数,进行隐式转换。程序如下所示:
#include<iostream>
class Fraction
{
public:
Fraction(int num, int den = 1) //one-argument只有一个参数
: m_numerator(num), m_denominator(den) {}
Fraction operator+ (const Fraction& f)
{
//return Fraction(this->m_numerator * f.m_denominator + f.m_numerator * this->m_denominator, this->m_denominator * f.m_denominator);
std::cout << (this->m_numerator * f.m_denominator + f.m_numerator * this->m_denominator) << "/" << (this->m_denominator * f.m_denominator) << std::endl;
}
private:
int m_numerator;
int m_denominator;
};
int main(int argc, char* argv[])
{
Fraction f(3,5);
Fraction d1 = f + 4; //自动将4转换成4/1
Fraction f1(4);
Fraction d2 = f1 + 4; //自动将4转换成4/1
return 0;
}
在这个例子中,通过构造函数可以自动将double型数值转换成Fraction对象,再通过Fraction operator+ (const Fraction& f)进行Fraction相加操作,返回值为Fraction类型。运行结果如下所示:
explicit-one-argument ctor
explicit关键字的作用就是防止类构造函数的隐式自动转换。explicit关键字只对一个参数的类构造函数有效,如果类构造函数参数大于等于两个时,是不会产生隐式转换的,所以explicit关键字也就无效。但是,也有一个例外,就是当除了第一个参数以外的其他参数都有默认值的时候,explicit关键字依然有效。此时,当调用构造函数时只传入一个参数,等效于只有一个参数的类构造函数,例子如下:
#include<iostream>
class Fraction
{
public:
explicit Fraction(int num, int den = 1)
: m_numerator(num), m_denominator(den) {}
Fraction operator+ (const Fraction& f)
{
//return Fraction(this->m_numerator * f.m_denominator + f.m_numerator * this->m_denominator, this->m_denominator * f.m_denominator);
std::cout << (this->m_numerator * f.m_denominator + f.m_numerator * this->m_denominator) << "/" << (this->m_denominator * f.m_denominator) << std::endl;
}
private:
int m_numerator;
int m_denominator;
};
int main(int argc, char* argv[])
{
Fraction f(3,5);
Fraction d1 = f + 4; //Error:no match for 'operator+' (operand types are 'Fraction' and 'int')
Fraction f1(4);
Fraction d2 = f1 + 4; //Error:no match for 'operator+' (operand types are 'Fraction' and 'int')
return 0;
}
当使用explicit-one-argument ctor之后,类构造函数不能自动隐式转换,double型数值不能转换成Fraction对象,编译时就会出错。