成員函數與資料成員


  1. 物件導向基本觀念:
    1. 傳統程式設計: (ds + ds + ds) * (f + f + f)
    2. 物件導向設計: (ds + f) * (ds + f) * (ds + f)
    3. 以資料庫觀念理解 C/C++ 的術語:
                      C               C++                     Database
                      structure       class                   table
                      variable        instance                record
                      field           data member             field/attribute
                      (???)           member function         (attribute)
              
      

    4. 在物件導向語言中, data member 與 member function 通稱為 attribute. 有些語言的語法甚至設計成讓物件的使用者分不出來一個 attriute 究竟是 data member 或是 member function.
  2. Member function (成員函數) and "this"
    1. 實例請參考
                      date.c           date.cc
      complex.c        complex0.cc
      school.c         school.cc
              
      

    2. 設計成員函數: 找出函數 f 中最主要的參數 x, 若其型別為 t, 則將 f 改宣告成 t 的成員函數.
                                              class t {
                      int f(t x, ...);            int f(...);
                                              };
      
                      f(a, ...);              a.f(...);
              
      

    3. 宣告方式: 同樣的函數, 在 C++ 中若成為成員函數, 則其參數個數往往比在 C 中的參數個數少一個.
    4. 使用方式: 把最重要的參數提到括弧外, 以 . 呼叫. 同理, 若有 t * p; 的宣告, 則可以 t->f(...); 呼叫.
    5. 定義方式: 在成員函數的實作中, 想像消失的參數其實是以隱含的參數 t * this 來傳遞, 因此可以透過 this->... 存取其資料成員 (欄位). 例如當 f 是透過 a.f(...) 呼叫時, 可以想像進入副程式時, 雖然沒有寫出來, 但是發生了:
                      t const * this = &a;
              
      

    6. 成員函數的定義中, this-> 可以省略.
    7. 不同的類別中可以有 signature 相同的成員函數, 為了區別, 在定義成員函數時, 必須加上 :: (scope resolution operator) 代表 "某個類別 某某成員函數". :: 前不冠任何類別, 則表示 "不屬於任何類別 ".
    8. 若主要參數 x 本來應該以 t const * x 的方式傳遞, 則變成成員函數後應將 const 置於函數的 "脖子". 養成將所有 member function 宣告成 const 的習慣, 當你確定這個 member function 不適用 const 時才不要用.
    9. 成員函數的定義寫在類別定義內者, 自動為 inline 函數.
    10. 作業: 修改 stack.c 將所有相關的函數改寫為成員函數.
    11. 作業: 在 date.cc 中加入 operator ==, operator ++ 等成員函數.
  3. static 成員函數: 沒有隱含參數 this 的成員函數.
    1. static 這個 keyword 只在宣告時寫出; 在定義時不應寫出.
    2. 呼叫時, 因為 static member fucntion 不作用於那一個特定的物件上 (它是屬於整個類別的函數!) 因此不應透過 . 或 -> 呼叫, 而應使用 ::
    3. 例: date.cc 中的 is_leap_year 可考慮改宣告為 static member function.
  4. static 資料成員: 這個類別的所有 instances 共用的一份資料.
    1. 主要用在統計等記錄與整個類別相關的資訊. 例: 記錄目前身份證發到第幾號.
    2. 除了宣告 (用 static) 之外要記得定義 (不加 static)!