您的位置:首页 > 编程语言 > C语言/C++

More Effective C++学习笔记-条款5|6

2017-10-08 14:35 691 查看

谨慎定义类型转换函数

有两种类型函数允许编译器进行这些转换:单参构造函数和隐试类型转换运算符。

例如:

class Name
{
public:
Name(const string &name){}; //string转换到Name
...
};

//有理数类
class Rational
{
public:
//转换int到有理数类
Rational(int numerator=0, int denminator=1){}
//转换Rational为double类型
operator double() const{}
};


上面的有理数类会在该情况下被调用:

Rational r(1,2);
double d = 0.5*r;   //r转换成double类型然后做乘法


其实我们真正想说的是为什么你不需要定义各种类型转换函数:

比如:6

Rational r(1,2);
cout << r;


其实你根本没有定义operator<<运算符,但是编译却没有问题,运行打印结果为1.2,这就是隐试类型转换发挥的作用。

如果非要使用转换函数,最好的方法就是写一个显示的成员函数例如:
double toDouble() const
来完成这个转换任务。

为了去除隐试转换可以使用explicit来修饰构造函数。

自增(increment)和自减(decrement)操作符的前缀形式与后缀形式的区别

class Int
{
public:
Int(int value): m_value(value){...}
Int(const Int& other){...}
Int& operator++() //++前缀
{
cout << "Int& operator++()" << endl;
++m_value;
return *this;
}
const Int& operator++(int)  //++后缀
{
cout << "const Int& operator++(int)" << endl;
Int temp(*this);
++m_value;
return std::move(temp);
}
Int& operator--() //--前缀
{
cout << "Int& operator--()" << endl;
--m_value;
return *this;
}
const Int& operator--(int)  //--后缀
{
cout << "const Int& operator--(int)" << endl;
Int temp(*this);
--m_value;
return std::move(temp);
}
private:
int m_value;
};


对于后缀形式,编译器默认传递一个参数0进去,以作为识别。

使用如下:

Int i;
++i;    //调用i.operator++()
i++;    //调用i.operator++(0)
--i;    //调用i.operator--()
i--;    //调用i.operator--(0)


特别要注意:前缀形式返回一个引用,后缀形式返回一个const类型

为什么是const类型呢,假如返回的不是const类型,我们看以下示例:

Int i;
i++++;  //这样就可以编译过   而内置的int、double等类型是不可以通过的
//等同于
i.operator(0).operator(0);


这样就很明显了,因为后缀返回一个临时的对象,而原来的i的值是不会进行第二次自增操作的。

根据以上总结,为了效率考虑,尽量使用前缀形式自增
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息