C++关键字:explicit与构造函数浅析

C++关键字:explicit与构造函数

C++关键字explicit常常用来放在接受一个实参的构造函数(non-explicit-one-argument-constructor)前,以防止编译器在某些条件下的默认行为——调用该构造函数来实现类型转换。当声明一个构造函数为explicit时,表示这个构造函数只能通过用户显示调用来创建对象。

首先谈谈explicit常常使用的地方:non-explicit-one-argument-constructor——非显式接收一个实参的构造函数。

class Fraction
{
public:
	Fraction(int num, int den=1):m_numerator(num), m_denominator(den)//接收两个参数,分子和分母,分母的默认值为1
	{
        cout<<"call constructor"<<" num: "<< num<< " den: "<< den <<endl;
    }
	~Fraction()
	{}
	Fraction operator+ (const Fraction& f)
	{
		int den = this->m_denominator * f.m_denominator;//通分
	    int num = this->m_numerator * f.m_denominator + f.m_numerator * this->m_denominator;
		return Fraction(num, den);
	}
private:
	int m_numerator; //分子
	int m_denominator; //分母
};

上面这段代码定义了一个描述分数的类Fraction,该类含有两个数据成员m_numerator,m_denominator分别表示分子和分母。Fraction类的构造函数接受两个参数分别代表分子和分母,其中分母有默认值1(这是合理的,比如整数4可以写成分数4/1)。这个构造函数虽然有两个参数,但是真正调用这个构造函数只需要给出第一个参数,而第二个参数使用默认值即可,这种在调用时只需要传递一个参数的构造函数叫做non-explicit-one-argument-constructor,下面看看在有这种构造函数时,编译器使用该构造函数进行类型转换的默认行为

主函数:

int main()
{
    Fraction f(3, 5);
    Fraction f2 = f + 4;
    return 0;
}

主函数中第二行Fraction f2 = f + 4;调用Fraction重载的+运算符,+运算符接收的右操作数类型为Fraction,实际语句中的数为整数4,这时编译器为了让该语句通过编译,会将4作为实参,调用上面定义的non-explicit-one-argument-constructorFraction(int num, int den=1),调用完毕之后,4被转换为Fraction类,所以加法操作能够顺利执行了。如下:
在这里插入图片描述
main中创建分数3/5第一次调用构造函数,当执行加法时,编译器自动调用构造函数将4转换为Fraction,最后在重载运算符+内,显示调用构造函数创建对象并返回。




有时候这种编译器“好心”的转换并不是我们想要的。

如果不需要这种默认转换功能则只需要在构造函数前加入explicit关键字即可。

explicit Fraction(int num, int den=1):m_numerator(num), m_denominator(den)//接收两个参数,分子和分母,分母的默认值为1
{
    cout<<"call constructor"<<" num: "<< num<< " den: "<< den <<endl;
}

这时再执行main函数,语句Fraction f2 = f + 4;则会报如下的错误error: no match for 'operator+' (operand types are 'Fraction' and 'int')4不能转换成Fraction,从而因为没有定义Fraction + int的方法报错。

编译器不会帮我们进行自动类型转换,而想让该语句通过只能显式调用构造函数将4转化为Fraction。Fraction f2 = f + Fraction(4);

以上就是explicit最常用来使用的地方了,就是在只接受一个实参的构造函数前加入explicit关键字,表示该构造函数只是构造函数,编译器不再自动使用构造函数进行类型转换,除非显示调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值