2015年6月27日 星期六

class讓資料變聰明

Q : 輸入n個正整數,使用 class 設計求最大公因數程式



char bool int long float double 這些在 C 時期就已存在的基本資料型態,本身只是單純的資料沒有執行能力,不易用來開發物件導向程式。

C++ 剛誕生時,最初的名字稱為「C with Classes」,也就是具有 class 的 C 語言,這意味著 class 的加入,是 C++ 更上層樓成為物件導向程式語言的開端。

class 是一種自訂型態,其內容包含資料成員 (Data member) 和成員函式 (Member function) 兩大類。當 class 設計好之後,就可用來在程式中宣告並產生物件。由於 class 包含了資料和函式(Member function),所以物件本身就具有執行能力。

以下即改寫上一篇程式,用 class 來取代主程式中的 int 陣列與指標

#include <iostream>

class myData
{
//公用區段,class內外部程式均可存取
public:
   //Data member
   int len;
   int *data; //用來存放所有輸入資料的記憶空間指標

   //Member function
   myData() //建構函式,當物件產生時會自動執行
   {
       len=0; //資料長度歸0
       data=0; //資料指標歸0
   }

   ~myData() //解構函式,當物件消滅時會自動執行
   {
       if (data!=0)
         delete [] data; //釋放data記憶空間
   }

   void add(int d)
   {
     if (data!=0) //已經存在舊資料
     {
       int *newptr=new int[len+1]; //動態配置比原來多一個單位的記憶空間
         for(int i=0; i<len; i++)
             newptr[i]=data[i]; //把舊資料複製到新的位置
       delete [] data; //釋放舊的記憶空間
       data=newptr; //資料指標指向新的位置
     } else
       data=new int[1]; //沒有舊資料,直接動態配置記憶空間

     data[len]=d; //把參數d放在最後的位置
     len++; //資料長度+1
   }
};

int common_divisor(int a, int b) //遞迴函式1
{
   if(a%b==0) //如果a/b餘0,b就是公因數
      return b;
   else if(a>b)
      return common_divisor(a-b,b); //a值較大,把a減掉b繼續測試
   else
      return common_divisor(b,a); //b值較大,交換位置重新測試
}

int common_divisor(int d[], int n) //遞迴函式2
{
   if(n==1)
     return d[0];
   if(n==2)
     return common_divisor(d[0],d[1]);
   if(n>2)
     return common_divisor(common_divisor(d,n/2),
                                     common_divisor(&d[n/2],n-n/2) );

   return 0; //n小於1才會發生
}

int main()
{
   int d;
   class myData object1;

   std::cout << "請輸入n個正整數,輸入完成請按 Ctrl-Z" << std::endl;
   while ( std::cin >> d )
      object1.add(d);

   std::cout << "最大公因數=" << common_divisor(object1.data, object1.len);
   return 0;
}

程式中設計了一個 class myData,它包含了 data、len 兩個資料成員,及建構函式、解構函式與 add 函式,之後於主程式中宣告了 myData 類別的 object1 物件,主程式不用再理會記憶體管理問題,只要以 object1.add(d); 去添加使用者輸入的數字即可,除了程式更簡易清晰,將來若想改善記憶體管理的效能,也只要修改 class myData 即可,後續維護的工作更容易。

沒有留言:

張貼留言