C v.s. Cpp

C
type(built-in,struct) -> Variables
Cpp
class,struct -> Objects

guard头文件的防卫式声明

#ifndef __COMPLEX__
#define __COMPLEX__
...
#endif

头文件的布局

#ifndef __COMPLEX__
#define __COMPLEX__
#include <cmath>

//前置声明forward declarations
class ostream;
class complex;
complex&
    __doapl (complex* ths, const complex& r);

//类声明 class declarations
class complex{
...
}

//类定义class definition
complex::function ...

#endif

class template模板

类似Java的泛型

inline内联

    double real () const { return re; }
    double imag () const { return im; }

access level访问等级

public private protected

constructor(ctor)构造函数

complex (double r = 0, double i = 0): re (r), im (i) { }
//上述为初始列方法,等同于下面
complex (double r = 0, double i = 0) {re =r; im = i;}

overloading重载

complex (double r = 0, double i = 0): re (r), im (i) { }
complex () : re(0), im(0) {}
//不能构成重载,因为第一个complex有默认值

const member functions常量成员函数

    double real () const { return re; }
    double imag () const { return im; }
//假设上述函数没有const,在利用下面语句时会出现错误
{
const complex c1(2,1);
//因为前后const冲突
}

参数传递pass by value v.s pass by reference

//pass by value
    complex (double r = 0, double i = 0): re (r), im (i) { }
//pass by reference
    complex& operator += (const complex&);
//如果不希望被改变,可以加上const

friend友元

类似Java中的成员函数通过this取值

friend complex& __doapl (complex *, const complex&);

相同class的各个objects互为友元

class complex {
public:
    complex (double r = 0, double i = 0)
        : re(r), im(i)
    { }
    int func(const complex& param) {
        return param.re + param.im;}
private:
    double re, im;
};
//调用
{
    complex c1(2,1);
    complex c2;
    c2.func(c1);
//c2可以直接通过函数func获得c1的re和im
}

通过成员函数实现操作符重载

inline complex&
complex::operator += ([this],const complex& r) {
    return __doapl (this, r);
}
//假设有如下语句
c2 += c1;
//实际上是c2调用该重载操作符,this实际上为一pointer,指向c2,*上述[this]实际上不存在

上述代码的进一步分析

inline complex&
__doapl(complex* ths, const complex& r) {
    ...
    return *ths;
}
/*传递者无需知道接收者是以Reference形式接收的
  上述__doapl函数的返回值是一个pointer *ths,但其接收形式是引用 complex&
  这个过程将pointer类型给隐藏了起来
*/
inline complex&
complex::operator += ([this],const complex& r) {
    return __doapl (this, r);
}
//上述重载操作符采用complex&的原因如下,假设调用
c2 += c1;
//此时不会有问题,如果进行链式编程
c3 += c2 += c1;
//返回值就需要是complex&,因此返回值这么设计鲁棒性更强

通过非成员函数实现操作符重载

operator + (const complex& x, const complex& y) {
    return complex (real(x) + real(y),
                    imag(x) + imag(y));
}
/*此处返回值之所以不用reference而返回local object
  是因为不像上一例一般,返回值是传参进来的、已经存在的对象
  如果此处直接返回临时对象的reference,那么其生命周期在函数执行完毕后结束,reference也就没有意义了
  当然也可以在外部创建某一个temp对其进行操作,此时便可以返回reference
*/
inline complex
operator + (const complex& x, double y) {
    return complex (real(x) + y, imag(x));
}
/*上面的格式是 类()
  即临时对象 typename();
  类似于Java里的匿名对象
*/
inline complex
operator + (double x, const complex& y) {
    return complex (x + real(y), imag(y));
}