【effective C++笔记】C++ 中explicit 关键字

explicit 关键字用于构造函数的显式声明。显式和隐式的区分标准是在定义对象时用的是否用到了隐式转换。先来看一个简单的例子:

int i = 2;
cout << (i + 3.5) << endl;

得到的结果是5.5 。 i 是int型,和一个float小数相加就把结果隐式转化为float 型。与它对应的是强制转换,也就是显示转换。

在类的构造函数中,也有隐式转换,看下面的例子:

#include <iostream>
using namespace std;

class Rational
{
public:
    Rational(int numerator = 0, int denominator = 1);
    ~Rational(){}
    int get_n() const; // 只能调用不能修改数据成员
    int get_d() const;
protected:
private:
    int n;
    int d;
};

Rational::Rational(int numerator, int denominator)
                    :n(numerator), d(denominator){}

int Rational::get_n() const
{
    return n;   
}

int Rational::get_d() const
{
    return d;
}

int main()
{
    Rational ra1 = 12;
    Rational ra2 = Rational(12);
    cout << "rational 1 : " << ra1.get_n() <<"  / ” << ra1.get_d() << endl;
    cout << "rational 2 : " << ra2.get_n() <<" / " << ra2.get_d() << endl;
    system("pause");
    return 0;
}

mian() 函数中的Rational ra1 = 12;Rational ra2 = Rational(12);是等价的,第一种就是隐式转换。

要想不这么做,可以在构造函数声明时添加一个explicit , 然后Rational ra1 = 12;这一句就不能够进行隐式转换了,就会报错,只能通过调用构造函数来初始化对象。

在条款24中:如果所有参数皆需要类型转换,请为此采用non-member函数。有如下代码:

#include <iostream>
using namespace std;

class Rational
{
public:
     const Rational operator* (const Rational& rhs); //rhs 为右操作数
     Rational(int numerator = 0, int denominator = 1);
    ~Rational(){}
    int get_n() const; // 只能调用不能修改数据成员
    int get_d() const;
protected:
private:
    int n;
    int d;
};

Rational::Rational(int numerator, int denominator)
                    :n(numerator), d(denominator){}

int Rational::get_n() const
{
    return n;   
}

int Rational::get_d() const
{
    return d;
}

const Rational Rational::operator *(const Rational &rhs)
{
    this->n = this->n * rhs.n;
    this->d = this->d * rhs.d;
    return *this;   
}

int main()
{
    Rational onehalf(1,2);
    Rational result;
    result = onehalf * 2;
    cout << "result : " << result.get_n() << " / " << result.get_d() << endl;
    system("pause");
    return 0;
}

这段代码声明了一个有理数的类,重载了一个运算符,想实现有理数和整数的运算。result = onehalf * 2 可以成功,但是result = 2 * onehalf 就会失败,为什么呢?这是因为onehalf是一个对象,有相应的operator 函数,当遇到数值2时,就会出现一个隐式转化的以2为分子的对象,然后实现乘积。反过来,2这个数值没有相应的类,也就没有了operator* 函数。

同样的,在构造函数中声明一个explicit 的话,不管是result = onehalf * 2还是result = 2 * onehalf都会导致失败。

好的做法是将重载的运算符作为一个non-member 函数,注意member函数的反面是non-member 函数,而不是friend函数。请记住:无论何时能避免friend函数就尽量避免,因为像真是世界一样,朋友带来的麻烦往往多过于价值。额。。。这个还真不好说。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值