【Exceptional C++(9)】CLASS技术
2018-01-29 本文已影响4人
downdemo
问题
- 下面的class有一些不好的代码风格和错误,找出来
class Complex
{
public:
Complex(double real, double imaginary = 0)
: _real(real), _imaginary(imaginary)
{}
void operator+(Complex other)
{
_real = _real + other._real;
_imaginary = _imaginary + other._imaginary;
}
void operator<<(ostream os)
{
os << "(" << _real << "," << _imaginary << ")";
}
Complex operator++()
{
++_real;
return *this;
}
Complex operator++(int)
{
Complex temp = *this;
++_real;
return temp;
}
private:
double _real, _imaginary;
};
解答
Complex(double real, double imaginary = 0)
: _real(real), _imaginary(imaginary)
{}
- 构造函数允许发生隐式转换,由于第二个参数有默认值,此函数可以看作单一参数的构造函数,并因此得允许一个double转换为Complex,这样的转换可能并非意图之中,所以把构造函数设为explicit比较好
void operator+(Complex other)
{
_real = _real + other._real;
_imaginary = _imaginary + other._imaginary;
}
- operator+使用pass-by-value,效率低,尽量用const&传参,此外a=a+b应该写成a+=b,这样做对double的加法虽然没什么提升,但是对class的加法效率改善很明显
- 尽量写a op=b而不要写a=a op b。因为operator+=直接作用于左件,且传回的是引用,而operator+必须传回一个临时对象
T& T::operator+=(const T& other)
{
// ...
return *this;
}
const T operator+(const T& a, const T& b)
{
T temp(a);
temp += b;
return temp;
}
- 如果提供了某个子运算(如operator+)的标准版,请同时提供一个assignment版(如operator+=)
- operator+不应该是member function,当允许其他类别隐式转换为Complex时,operator+可能无法正常工作,比如对Complex对象只能写a = b + 1.0而不能写a = 1.0 + b,因为member operator+要求左件为Complex
- 使用以下准则决定一个运算是否为member function
- 一元运算子应该是member
- = () [] -> 必须是member
- assignment版运算子(+= -= *= /=)都必须是member
- 其他所有二元运算子都应该是nonmember
- operator<<不应该成为mmeber function,且应该传回ostream&
Complex operator++()
{
++_real;
return *this;
}
- 前置累加运算子应该传回reference to non-const,所以返回类型应是Complex&
Complex operator++(int)
{
Complex temp = *this;
++_real;
return temp;
}
- 后置累加运算子应传回const Complex,这样可以阻止类似于a++++的代码
- 后置累加运算子应该以前置累加运算子为本
- 避免触及保留名称,不要在变量名前加下划线,可以加在后面
- 下面是修改后的版本
class Complex
{
public:
explicit Complex(double real, double imaginary = 0)
: real_(real), imaginary_(imaginary)
{}
// 定义operator+=,将operator+设为non-member
Complex& operator+=(const Complex& other)
{
real_ += other.real_;
imaginary_ += other.imaginary_;
return *this;
}
Complex& operator++()
{
++real_;
return *this;
}
Complex operator++(int)
{
Complex temp(*this);
++*this;
return temp;
}
// 定义Print
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);
}