Key:
- Item1: 防卫式声明:避免头文件的重定义
- Item2: 构造函数使用 initialization list
Detail: Effective C++ Item04: Make sure that objects are initialized before they’re used- Item3: 使用 const 限定不需要改变的对象
Detail: Effective C++ Item03: Use const whenever possible- Item4: 参数传递采用 pass by reference(to const) 而非 pass by value;
Detail: Effective C++ Item20: Prefer pass-by-reference-to-const to pass-by-value- Item5: return by reference 例外: 永远不要返回 local object 的 reference, 使用 local object 一定要注意其生命周期
Detail: Effective C++ Item 21: Don’t try to return a reference when you must return an object- Item6: 数据成员定义为 private 成员, 通过相应的 public 函数对其进行访问
Detail: Effective C++ Item 22: Declare data members private- Item7: 函数重载要尽量考虑多种使用情况;操作符重载尤其注意连续使用的情况
Detail: Effective C++ Item11: Have assignment operators return a reference to *this
Task:
- Realize complex, a class without pointer member, including merbers as following:
- private member 1: data: re(real), im(imag)
- private member 2: friend function:
complex& __doapl( ) to realize operator +=,complex&__doami( ) to realize operator -=, complex&__doaml( ) to realize operator *=;- public member 1: real( ) / imag( ) to get re / im;
- public member 2: constructer: complex( );
- public member 3: operator +=, -=, *=, /=;
- Some global functions to use complex: opreator +, -, *, /;
real( ), imag( ) to get re / im; opreator << to output a complex
Code
#ifndef MYCOMPLEX_H//Defence declaration : Item 1
#define MYCOMPLEX_H
class complex;
complex&
__doapl(complex*, const complex&);
class complex {
public:
// Initialization list: Item 2
complex(double r = 0, double i = 0) : re(r), im(i) { }
//const member function: Item 3
double real() const { return re; }
double imag() const { return im; }
//pass by reference (to const): Item 4
complex& operator += (const complex& );
private:
double re, im;// private data member : Item 7
friend complex& __doapl(complex*, const complex&);
};
inline double
imag (const complex& x)
{
return x.imag ();
}
inline double
real (const complex& x)
{
return x.real ();
}
inline complex&//return by reference: when return a non-local object, *ths is existed before __doapl is called & after __doapl return
__doapl(complex* ths, const complex& r) {
ths->re += r.re;
ths->im += r.im;
return *ths;// *ths is a complex class object while ths is a pointer!
}
inline complex&
complex::operator += (const complex& r) {
return __doapl(this, r);
}
inline complex
operator + (const complex& c1, const complex& c2) {
return complex(real (c1) + real (c2), imag (c1) + imag (c2));
}
inline complex
operator + (const complex& c, double d) {
return complex (real (c) + d, imag (c));
}
inline complex // return by value: Item 5; complex(real(c)+d, image(c)) is a local object!
operator + (double d, const complex& c) {
return complex (real (c) + d, imag (c)); //make sure that a object is initialized before it is used
}
inline complex
operator - (const complex& c) {
return complex(-real (c), -imag (c));
}
inline complex
conj (const complex& c) {
return complex(real (c), -imag (c));
}
inline bool
operator == (const complex& c1, const complex& c2) {
return real(c1) == real(c2) && imag(c1) == imag(c2);
}
//operator <<: for the case like cout << c1 << endl;
ostream&
operator << (ostream& os, const complex& x)
{
return os << '(' << real (x) << ',' << imag (x) << ')';
}
#endif
Q&A:
- Q: Why is operator + designed as a global function but not a member function?
为什么把操作符 + 设计为全局函数而非成员函数?
A: If operator + is a member function, then “complex + double” will be limited.
如果操作符 + 被设计为成员函数,那么“complex + double” 的使用情况会受到限制
Similar : operator >> designed as a global function
操作符 >> 考虑
cout << complex1 << endl;