1. 程式人生 > >c++入門之 再話類

c++入門之 再話類

對於類,其結構並不難,但要理解其設計思想也並不容易,在此,我們可以通過下面的程式碼進一步理解和使用類:

 1 # ifndef VECTOR_H_
 2 # define VECTOR_H_
 3 # include "iostream"
 4 
 5 namespace VECTOR //注意,這裡對這個類定義了名稱空間,實際上,在寫自己的類時,也應該定義自己的名稱空間
 6 {
 7     class Vector
 8     {
 9     public:
10         enum Mode{RECT,POL};//因為這個量需要使用者自己去設定
11     private:           //
注意:私有成員(無論是函式還是變數)只能被類內部成員訪問 12 double x; 13 double y; 14 double mag; 15 double ang; 16 Mode mode; 17 18 void set_mag(); 19 void set_ang(); 20 void set_x(); 21 void set_y(); //體會將這些函式放在這裡的用意!! 22 public: //
共有成員可以被所有訪問!!理解這個意思 23 Vector();//建構函式 24 Vector(double n1,double n2,Mode form = RECT);//注意,這裡有預設引數 25 void reset(double n1, double n2, Mode form = RECT); 26 ~Vector();//解構函式 27 double xval() const{ return x; } 28 double yval() const{ return y; } 29 double
magval() const{ return mag; } 30 double angval() const{ return ang; } 31 void polar_mode(); 32 void rect_mode(); 33 34 Vector operator+(const Vector &b) const; 35 Vector operator-(const Vector &b) const; 36 Vector operator-() const; 37 Vector operator*(double n) const; 38 39 friend Vector operator*(double n, const Vector &a);//注意這裡採用了友元函式的做法,應該顯示包含所有引數 40 friend std::ostream & operator<<(std::ostream &os, const Vector & v);//昨天沒有思考返回引用是否存在問題???因為區域性變數被銷燬的問題 41 }; 42 43 } 44 # endif

該類定義中:除了備註的一些以外,總結這麼幾點:

1 定義了一個類的時候,限定了該類的名稱空間通常是一件好事,以免自己的變數和別人的發生了衝突

2   公有還是私有並無界限之分,完全取決於程式的功能。

3  我們通常會發現:當定義一個類成員函式時,通常需要:建構函式,解構函式,甚至友元函式

4  私有成員(無論是變數還是函式)只能被類內部的成員進行訪問,而共有成員 可以被其他類甚至其他任何東西訪問。究其本質:公有部分 是提供的介面

下面給出該定義:

  1 # include"cmath"  //從下文的呼叫方法來看,這裡應該是函式庫,而不是類庫
  2 # include "vector.h"
  3 using std::sqrt;   //注意 std 包含了很多
  4 using std::sin;
  5 using std::cos;
  6 using std::atan;
  7 using std::atan2;
  8 using std::cout;
  9 
 10 namespace VECTOR  //名稱空間的意義是很有必要的
 11 {
 12     const double Rad_to_deg = 45.0 / atan(1.0);
 13     void Vector::set_ang()
 14     {
 15         mag = sqrt(x*x + y*y); //求極長
 16     }
 17 
 18     void Vector::set_ang()
 19     {
 20         if (x == 0.0  && y == 0.0)
 21             ang = 0.0;
 22         else
 23             ang = atan2(y, x);//求極角
 24     }
 25 
 26     void Vector::set_x() //這些是私有函式
 27     {                 
 28         x = mag*cos(ang);//私有函式可以訪問私有變量表明私有成員也可以相互訪問
 29     }
 30 
 31     void Vector::set_y()
 32     {
 33         y = mag*sin(ang);
 34     }
 35 
 36     Vector::Vector()
 37     {
 38         x = y = mag = ang = 0.0;
 39         mode = RECT;
 40     }
 41 
 42     Vector::Vector(double n1, double n2, Mode form)
 43     {
 44         mode  = form;
 45         if (form == RECT)
 46         {
 47             x = n1;
 48             y = n2;
 49             set_mag();//訪問了私有成員
 50             set_ang();//體會這裡的設計思想
 51         }
 52         else if (form == POL)
 53         {
 54             mag = n1;
 55             ang = n2;
 56             set_x();
 57             set_y();
 58         }
 59         else
 60         {
 61             cout << "Incorrect 3rd argument to Vector()--";
 62             cout << "vector set to 0\n";
 63             x = y = mag = ang = 0.0;
 64             mode =RECT;
 65         }
 66     }
 67     void Vector::reset(double n1, double n2, Mode form)
 68     {
 69         mode = form;
 70         if (form = RECT)
 71         {
 72             x = n1;
 73             y = n2;
 74             set_mag();
 75             set_ang();
 76         }
 77         else if (form = POL)
 78         {
 79             mag = n1;
 80             ang= n2;
 81             set_x();
 82             set_y();
 83         }
 84         else
 85         {
 86             cout << "Incorrect 3rd argument to Vector()--";
 87             cout << "vector set to 0\n";
 88             x = y = mag = ang = 0.0;
 89             mode = RECT;
 90         }
 91     }
 92     Vector::~Vector()//
 93     {
 94 
 95     }
 96 
 97     void Vector::polar_mode()
 98     {
 99         mode = POL;
100     }
101 
102     void Vector::rect_mode()
103     {
104         mode = RECT;
105     }
106 
107     Vector Vector::operator+(const Vector &b) const
108     {
109         return Vector(x + b.x, y + b.y);
110     }
111 
112     Vector Vector::operator-(const Vector &b) const
113     {
114         return Vector(x - b.x, y - b.y);
115     }
116 
117     Vector Vector::operator-() const
118     {
119         return Vector(-x, -y);
120     }
121 
        Vector Vector::operator*(double n) const
        {
return(n*x,x*y)
}

122 Vector operator*(double n, const Vector & a) 123 { 124 return a*n; //注意,雖然這裡進行了返回,但並沒有結束,而是繼續呼叫了成員函式, 125 } 126 127 std::ostream & operator<<(std::ostream & os, const Vector & v) 128 { 129 if (v.mode == Vector::RECT) 130 os << "(x,y) = (" << v.x << "," << v.y << ")"; 131 else if (v.mode == Vector::POL) 132 { 133 os << "(m,a) = (" << v.mag << "," << v.ang + Rad_to_deg << ")"; 134 } 135 else 136 os << "Vector object mode is invalid"; 137 } 138 }

 

1.  我們注意107行和112行的程式碼:本質上,進行了加法和減法之後,得到的是一個新的類物件,但由於這個類物件不止一種表示形式(直角座標和極座標),這裡巧妙的利用了 返回建構函式的執行。這告訴我們:建構函式並不僅僅用於初始化,建構函式的本意:構造新的物件,一定要認識這一本質特徵和思想。

2  我們注意124行的程式碼:return a*n; 本質上,物件乘以一個數無法實現,但這裡,其實,並沒有返回,而是回去重新呼叫了上面的*。

3 注意:129行和131行:if (v.mode == Vector::RECT)。為何要加Vector::RECT而不是RECT,這是因為:

友元函式雖然在public中,但友元函式並不在類作用域中!!! 這對於所有友元函式都成立!!!