要注意培養正規的、大氣的編程習慣。
1、基於對象(Object Based):面向單一class的設計。
class有兩種經典的分類:
一種不帶有指針
另一種帶有指針
2、面向對象(Object Oriented):面對的是多重classes的設計,classes和classes之間的關係。
-繼承
-複合
-委託
3、推薦書籍
本文所談的對象是不帶有指針的類(Class without pointer);
具體的分析了類的組成,重點介紹類方法的設計準則;
主要是內聯函數,參數傳遞,返回值傳遞,友元函數以及操作符重載在類設計中的使用。
下面的示例程序來自於--侯捷老師的網絡課程《C++面向對象高級開發》。
通過程序及註釋詳細的介紹Class without pointer的設計。
complex.h
//寫在前面
//1.關於內聯函數:
// 如果函數在body內定義,這樣便成爲了inline的候選人。
// 如果在body之外定義,默認不是inline函數。需要在函數的前面加inline關鍵字。
// 在聲明時寫不寫inline沒有影響,建議不寫。
// 是否真的成爲inline函數,最終由編譯器決定。
//2.不帶指針的類多半不用自己寫析構函數。
//3.參數傳遞
// 值傳遞:儘量不要使用值傳遞,不然會出現大量的拷貝。
// 引用傳遞:相當於傳指針,速度很快。
// const引用,保證傳進去的值不會被修改。
//4.返回值傳遞
// 儘量傳遞引用,局部變量不能作爲引用返回。
//5.friend友元函數
// 可以直接讀取對象內部的私有成員;
// 相同class的各個objects互爲friends;
// 友元會破壞類的封裝性,不宜多用。
//防衛式聲名頭文件
#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__
class complex;
complex&
__doapl(complex* ths, const complex& r);
complex&
__doami(complex* ths, const complex& r);
complex&
__doaml(complex* ths, const complex& r);
class complex
{
public:
//最好使用初始化列表的方式進行初始化,比起在函數體內進行賦值,效率會高。
complex(double r = 0, double i = 0) : re(r), im(i) { }
complex& operator += (const complex&);
complex& operator -= (const complex&);
complex& operator *= (const complex&);
//常量成員函數,不改變對象內的數據。
double real() const { return re; }
double imag() const { return im; }
//數據一定放在private裏面
private:
double re, im;
friend complex& __doapl(complex *, const complex&);
friend complex& __doami(complex *, const complex&);
friend complex& __doaml(complex *, const complex&);
};
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);
}
inline complex&
__doami(complex* ths, const complex& r)
{
ths->re -= r.re;
ths->im -= r.im;
return *ths;
}
inline complex&
complex::operator -= (const complex& r)
{
return __doami(this, r);
}
inline complex&
__doaml(complex* ths, const complex& r)
{
double f = ths->re * r.re - ths->im * r.im;
ths->im = ths->re * r.im + ths->im * r.re;
ths->re = f;
return *ths;
}
inline complex&
complex::operator *= (const complex& r)
{
return __doaml(this, r);
}
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)
{
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));
}
inline complex
operator - (const complex& x, const complex& y)
{
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));
}
inline complex
operator * (const complex& x, const complex& y)
{
return complex(real(x) * real(y) - imag(x) * imag(y),
real(x) * imag(y) + imag(x) * real(y));
}
inline complex
operator * (const complex& x, double y)
{
return complex(real(x) * y, imag(x) * y);
}
inline complex
operator * (double x, const complex& y)
{
return complex(x * real(y), x * imag(y));
}
complex
operator / (const complex& x, double y)
{
return complex(real(x) / y, imag(x) / y);
}
inline complex
operator + (const complex& x)
{
return x;
}
inline complex
operator - (const complex& x)
{
return complex(-real(x), -imag(x));
}
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 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;
}
#include <cmath>
inline complex
polar(double r, double t)
{
return complex(r * cos(t), r * sin(t));
}
inline complex
conj(const complex& x)
{
return complex(real(x), -imag(x));
}
inline double
norm(const complex& x)
{
return real(x) * real(x) + imag(x) * imag(x);
}
#include <iostream>
using namespace std;
ostream&
operator << (ostream& os, const complex& x)
{
return os << '(' << real(x) << ',' << imag(x) << ')';
}
#endif //__MYCOMPLEX__
complex-test.cpp
#include "complex.h"
int main()
{
complex c1(2, 1);
complex c2(4, 0);
cout << c1 << endl;
cout << c2 << endl;
cout << c1 + c2 << endl;
cout << c1 - c2 << endl;
cout << c1*c2 << endl;
cout << c1 / 2 << endl;
cout << conj(c1) << endl;
cout << norm(c1) << endl;
cout << polar(10, 4) << endl;
cout << (c1 += c2) << endl;
cout << (c1 == c2) << endl;
cout << (c1 != c2) << endl;
cout << +c2 << endl;
cout << -c2 << endl;
cout << (c2 - 2) << endl;
cout << (5 + c2) << endl;
return 0;
}