面向对象C++程序设计 - 01

常量成员函数 const member functions

class complex {
public:
complex (double r = 0, double i = 0) : re(r), im(i) { }
complex& operator += (const complex&);
double real() const { return re; } // ①
double imag() const { return im; }
private:
double re, im;
}
{
complex c1(2,1);
cout << c1.real();
cout << c1.imag();
}
{
const complex c1(2,1); // const说明c1的值不能改变
cout << c1.real(); // 如①没有加const,则说明可能改变值,这里会有编译错误
cout << c1.imag();
}

注意在①处需要加上关键字const,用以说明调用这个函数不会改变re的值,不然第二段代码片段会出现编译错误。const的位置在小括号后,花括号前。

操作符重载 operator overloading

成员函数

inline complex& __doapl (complex* ths, const complex& r) {
ths->re += r.re;
ths->im += r.im;
return *ths;
}
inline complex& complex::operator += (const complex& r) {
return __doapl (this, r);
}
{
complex c1(2,1);
complex c2(5);
c2 += c1; // ①
}

在进行①这条语句时,相当于对象c2调用+=函数,此时c2会作为this隐性地传入+=函数中。事实上每个对象在调用类的成员函数时,都会把指向当前对象的指针(this指针)作为参数传入。写代码的时候参数表不必写也不能写上这个this。

由于使用者可能连串使用+=操作符,如:

c3 += c2 += c1;

perator+=的返回值必须是complex&,而不能是void。

非成员函数

inline double imag(const complex& x) {
return x.imag();
}
inline double real(const complex& x) {
return x.real();
}
inline complex operator + (const complex& x, const complex& y) {
// complex()创建的是临时对象(temp object)
return complex (real(x) + real(y), imag(x) + imag(y));
}
inline complex operator + (const complex& x, double y) {
return complex (real(x) + y, imag(x));
}
inline complex operator + (double x, const complex& y) {
return complex (x + real(y), imag(y));
}
complex c1(2,1);
complex c2;
c2 = c1 + c2;
c2 = c1 + 5;
c2 = 7 + c1;

为应对使用者的不同使用方法,需要写不同的函数(并不止以上3个)。由于不是成员函数,自然也就不会有this指针被作为参数传入。并且由于返回对象是local object,故这三个函数不能return by reference。

inline complex operator + (const complex& x) {
return x;
}
inline complex operator - (const complex& x) {
return complex (-real(x), -imag(x));
}

一元操作符取反和二元操作符加减,可以根据参数个数加以区分。这里“-”返回对象也是临时对象,不能return by reference。“+”理论上没有返回临时对象,是可以return by reference,但标准库没有这么做。

inline bool operator == (const complex& x, const complex& y) {
return real(x) == real(y) && imag(x) == imag(y);
}
inline bool operator == (const complex& x, double y) {
return real(x) == y && imag(x) == 0;
}
inline bool operator == (double x, const complex& y) {
return x == real(y) && imag(y) == 0;
}
// !=类似,这里没有新的语法
// 共轭复数
inline complex conj (const complex& x) {
return complex(real(x), -imag(x));
}
#include <iostream>
// 由于os会改变,所以‘ostream& os’之前不能加const
ostream& operator << (ostream& os, const complex& x) {
return os << '(' << real(x) << ',' << imag(x) << ')';
}
{
complex c1(2,1);
cout << conj(c1);
cout << c1 << conj(c1);
}

对于<<操作符重载只能选择全局的,不能选成员函数。因为<<操作符只能作用于左边的cout,cout是标准库早就写好的,不能认识现在由程序员所创建的类型。由于<<可以连用,所以返回类型是ostream&,换成返回结果是void,则不能连用<<。