complex.h
#ifndef __COMPLEX__
#define __COMPLEX__
#include <cmath>
//前置声明
class ostream;
class complex;
complex&
__doapl (complex* ths, const complex& r);
//类声明(函数若在class内部定义完成,便自动成为inline候选人【对编译器的建议】)
//翻译:请编译器尽量把该函数翻译为inline函数
//1
class complex {
private://一般建议数据部分封装为private权限
double im, re;
friend complex& __doapl (complex* , const complex &);//友元【2-1】
//友元是对于某些对象的“例外”,如现在对于函数__doapl例外,该函数可以访问complex的私有变量
//【private和public域可以交错编写】
public://函数有区分是私有的或共有的
complex (double r = 0,double i = 0) //默认实参
: re(r), im(i) //initialization list【初始列,初值列】//仅构造函数有此写法
{ }
//不允许以下函数重载【由于默认参数】
//complex () : real(0), imaginary(0) { }
complex& operator += (const complex& );
double real () const { return re; }//【对于不改变对象内容的函数,建议加上const关键字】
double imaginary() const { return im; }//【对于不改变对象内容的函数,建议加上const关键字】
//加不加有什么区别?
//思考如下在main()中调用的代码:
/*{
const complex c(2,1)
cout << c.real()
}
// c是一个常量,若real函数不是常函数,则调用real,**代表函数内部可以对c进行修改**
// 这显然是不允许的,【编译器会报错】
*/
//【相同class的各个objects互为friends(友元)】 //其实构造函数就体现了这个道理
double foo(const complex& param) {
return param.re + param.im;
}
};
//类定义
//2-1
inline complex&
__doapl (complex* ths, const complex& r) {//第一个参数会被改动,而第二个参数不会被改动,则第一个不加const第二个加const
ths->re += r.re;
ths->im += r.im;
return *ths;
}
inline complex&
complex::operator += (const complex& r) {
return __doapl(this, r);
}
//2-2
inline double
imaginary(const complex& x){
return x.imaginary() ;
}
#endif
//参数传递:pass by value vs. pass by reference(to const)【传值还是传引用】
//一般建议函数的参数全部设置为引用类型,而有时为了防止参数被改变,则加上const关键字。
//返回值传递:return by value vs. return by reference(to const)
//也建议使用引用
测试代码:
main.cpp
#include <iostream>
#include <windows.h>
#include "complex.h"
using namespace std;
int main(){
complex c1(1,2), c2(3,4);
__doapl(&c1, c2);
cout << "c1 = " << c1.real() << " + " << c1.imaginary() << "i" << endl;
cout << c1.foo(c1) << endl;
system("pause");
return 0;
}