C++ Exceptional Item 20 Class Mechanics
class Complex
{
public:
//可以由一个变量构造的类型,尽量把构造函数声明为explicit的,
//以避免隐式的类型转换
explicit Complex(double real, double imaginary = 0)
: real_(real), imaginary_(imaginary)
{
}
//operator+=返回此对象的引用
Complex& operator+=(const Complex& other)
{
real_ += other.real;
imaginary_ += other.imaginary_;
return *this;
}
//前置的++运算符同样返回此对象的引用,因此(++a) = 这种形式允许的,并且会改变a对象的值
Complex& operator++()
{
++real_;
return *this;
}
//后置的++运算符,返回的是一个内部的临时对象,所以要返回const类型的值,以避免程序对临时对象进行改变,
//如 (a++) = b这种形式是不允许的
const Complex operator++(int)
{
Complex temp(*this);
++*this;
return temp;
}
ostream& Print(ostream& os) const
{
return os << "(" << real_ << "," << imaginary << ")";
}
private:
double real_, imaginary_;
}
const Complex operator+(const Complex& lhs, const Complex& rhs)
{
Complex ret(lhs);
ret += rhs;
return ret;
}
ostream& operator<<(ostream& os, const Complex& c)
{
return c.Print(os);
}
小结:我觉得上面有以下几点需要注意:
1. 在声明类的构造函数时,当这个类的构造参数中只有一个变量或者有多个变量但其他变量有默认值时,这时,如果不需要隐式转换,最好把隐式转换用explicit禁止掉。
2. 注意几个运算符的声明方式,operator+=要返回这个类的引用。注意区分前置运算符++和后置运算符++的区别,前置运算符同样返回的是这个类的引用,而后置运算符++返回的是一个栈上的临时变量,所以返回类型是const A类型的。引用类型是不可以的,因为若是引用类型,就会引用到一个临时的栈上的变量,这绝对是是不可以的。