2015年3月25日 星期三

C++物件導向的基本知識(簡易函式化)

C++是一個物件導向的語言,當您的程式上萬行以後,您的程式會變得非常難改,如果沒將您的程式碼以物件化的方式管理,您會改得非常累

什麼是物件化呢,其實物件化就是模組化,總之大概的意思就是把一堆您要的東西打包在一個容器,當您要使用時,只需要知道這個容器的inputoutput,便可以使用它來簡化或者管理您的程式

物件可以是一個函式(function),一個struct或者class,又或者是一個namespace,甚至還有繼承關係(這很複雜,這裡先不管這個)

您可在主程式直接建立上面的東西,用一些程式表達給你看

class cat
{
    cat();
    ~cat();
    Void eat(){}
    Void dog(){}
};

void dog(){}

namespace abc
{
    class bcd
     {
         bcd(){}
         void eat(){}
         void find(){}
     };
}

namespace cba
{
     class bcd
     {
         bcd(){}
         void eat(){}
         void find(){}
     };
     class fun
     {
         fun(){}
         void eat(){
             void add(){}
             add();
         }
         void delete(){}
    };
}

簡單說,容器可以隨便您包來包去,只要你寫的對,都會Compiler過,只要Compiler過了,他就可以Link成一支程式,並且可以動(前提是你寫的對)

大型程式,你不會隨心所欲的包來包去,您是不可能寫得好的,因為你會卡東卡西,會把程式寫得很複雜,就算你有註解,可能最後外星人都看不懂

 
你要懂這句話,通常要寫過比較中大型的程式,或者比較複雜的程式,不然其實看到這裡就好了,因為你沒有相關經驗,你是看不懂的

 
舉個例子

下面有段假的程式,假設它的目的是要完成一個演算法,其中演算法您就當他有吧,我會把一些演算法內容用//演算法//表示(您就把他想成是程式碼要做某些計算或動作),設定用//設定//表示

當您在寫視窗程式時,難免會用一個button,做一些功能,例如最簡單的1+…+n,當你比較複雜時,程式一定會出現很多迴圈,很多行

我們先從最白癡的,把所有code都寫在一個函式裡面

//////////////////////////////////////////////////////////

//設定1//
//演算法1//
//設定1//
//演算法2//
//演算法3//
//設定1//

For(int I = 0;I < n;i++)
{
    //演算法4//
    //演算法5//
    For(int j = 0;j < m;j++)
    {
        //演算法6//
        For(int k = 0;k < o;j++)
        {
            For(int k = 0;k < o;j++)
            {
                //演算法7//
                //演算法8//
            }
        }
    }
}

For(int I = 0;I < n;i++)
{
    //演算法9//
    //演算法10//
    For(int j = 0;j < m;j++)
    {
        //演算法11//   
        //演算法12//  
        //演算法13//  
        //演算法14//  
    }
}

//演算法1//
//設定1//
//演算法2//
//演算法3//
//////////////////////////////////////////////////////////////

想想,我寫這樣您看得懂嗎,您一定不可能看懂,因為我也不知道在寫啥XD
總之他就是一堆程式碼,要完成一個功能,需要做複雜的運算

一般我們在寫程式時會寫一些註解,讓您的程式方便閱讀(當然一般太趕時我就不會註解的很詳細了,因為假設這演算法要寫2個小時,而你只有三個小時可以寫程式,您為了讓程式方便閱讀(假設您是新手),新手通常要研究要怎樣寫的才會人家看得懂),很細心的註解2個半鐘頭,,你剩半個小時可以寫code,你覺得你可以如期交卷嗎
 
這裡是假設您功能有能力完成,其實你照我這樣寫法會比較乾淨和漂亮,你也比較好改程式


第一步 註解
//////////////////////////////////////////////////////////

//這段在寫如何做A工作
//設定1//
//演算法1//
//設定1//
//這段在寫如何做B工作
//演算法2//
//演算法3//

//設定1//
//這裡在寫主要的演算法

For(int I = 0;I < n;i++)
{
    //演算法4//
    //演算法5//
    For(int j = 0;j < m;j++)
    {
        //這裡是寫主要的演算法程式判斷
        //演算法6//
        For(int k = 0;k < o;j++)
        {
            For(int k = 0;k < o;j++)
             {
                 //演算法7//
                 //演算法8//
             }
         }
    }
}

//這裡作結果判斷
For(int I = 0;I < n;i++)
{
    //演算法9//
    //演算法10//
    For(int j = 0;j < m;j++)
    {
        //演算法11//   
        //演算法12//  
        //演算法13//  
        //演算法14//  
    }
}

//更改畫面欄位和收尾
//演算法1//
//設定1//
//演算法2//
//演算法3//
//////////////////////////////////////////////////////////////
您看看這樣您是不是大約知道我在描述什麼了
我在註解一次,這是新手很白癡的註解法,您看看這樣註解您看不看得懂

 
錯誤註解
//////////////////////////////////////////////////////////
//宣告變數
//將程式某個欄位讀進來
//設定1//
//演算法1//
//設定1//
//這段在做氣泡排序法
//演算法2//
//這裡宣告變數
//A變數的用途
//B變數的用途
//演算法3//
//設定1//
//這裡在寫主要的演算法

For(int I = 0;I < n;i++)
{
    //A陣列找出最大值
    //演算法4//
    //B陣列找出最大值
    //演算法5//
    For(int j = 0;j < m;j++)
    {
        //判斷每一個資料誰最適合
        //演算法6//
        For(int k = 0;k < o;j++)
        {
            For(int k = 0;k < o;j++)
            {
                //演算法7//
                //演算法8//
            }
        }
    }
}

//這裡作結果判斷
//宣告變數
//C變數的用途
//D變數的用途

For(int I = 0;I < n;i++)
{
    //E變數的用途
    //F變數的用途
    //這個迴圈的用途
    //演算法9//
    //演算法10//
    For(int j = 0;j < m;j++)
    {
        //演算法11//   
        //演算法12//  
        //演算法13//  
        //演算法14//  
    }
}

//更改畫面欄位和收尾
//演算法1//
//設定1//
//演算法2//
//演算法3//
//////////////////////////////////////////////////////////////

懶得全部打,我想表達的意思,會不會註解太多,且太亂,您寫完後自己看得懂嗎

結論是重要關鍵的地方註解就好了,不要沒事找事做,通常是邊寫程式邊註解,你要想演算法就夠痛苦了,還有時間在那邊把註解弄得漂漂亮亮的,你確定在上班時有時間給你悠閒地漫遊在註解的藝術上嗎=.=

適當的註解可以幫助你更了解程式,當然盡量一些變數命名盡量有意義(通常我也很懶,不重要的就隨便取個r,cnt,count),這裡就不講那個(這您寫久應該要開始會的東西)

接下來您看,我對我上面的程式進行標色(通常程式碼不能上色的),有上色的是做同一件事情,也就可以把它當作一個物件


第二步 分辨哪些程式是做同一件事情的
//////////////////////////////////////////////////////////
//這段在寫如何做A工作
//設定1//
//演算法1//
//設定1//
//這段在寫如何做B工作
//演算法2//
//演算法3//
//設定1//

//這裡在寫主要的演算法

For(int I = 0;I < n;i++)
{
    //演算法4//
    //演算法5//

    For(int j = 0;j < m;j++)
    {
        //這裡是寫主要的演算法程式判斷
        //演算法6//
        For(int k = 0;k < o;j++)
        {
            For(int k = 0;k < o;j++)
            {
                //演算法7//
                //演算法8//
            }
        }
    }
}

//這裡作結果判斷
For(int I = 0;I < n;i++)
{
    //演算法9//
    //演算法10//
   For(int j = 0;j < m;j++)
   {
       //演算法11//   
       //演算法12//  
      //演算法13//  
       //演算法14//  
    }
}

//更改畫面欄位和收尾
//演算法1//
//設定1//
//演算法2//
//演算法3//

//////////////////////////////////////////////////////////////

您看我標色後,是不是只有五個顏色,一個顏色把它當作一個物件,您是不是把您的程式分成五個重要部分,目的是做什麼,就是讓您的Code變得簡潔,這裡僅僅需要用函式就可以讓您的code乾淨了,其實很簡單,就是一個物件把它放在一個函式裡面,最後再用呼叫函式的方法撰寫程式




第三步 物件化您的程式碼




//////////////////////////////////////////////////////////////

Void A()

{

//這段在寫如何做A工作

//設定1//

//演算法1//

//設定1//

//這段在寫如何做B工作

//演算法2//

//演算法3//

//設定1//

}




Void C()
{
     //這裡是寫主要的演算法程式判斷
     //演算法6//
     For(int k = 0;k < o;j++)
     {
         For(int k = 0;k < o;j++)
         {
             //演算法7//
            //演算法8//
         }
     }
 }

Void B()
{
     //這裡在寫主要的演算法
     For(int I = 0;I < n;i++)
     {
         //演算法4//
         //演算法5//
         For(int j = 0;j < m;j++)
         {
             C();
         }
     }
 }

Void D()
 {
     //這裡作結果判斷
     For(int I = 0;I < n;i++)
     {
         //演算法9//
         //演算法10//
         For(int j = 0;j < m;j++)
         {
             //演算法11//   
             //演算法12//  
             //演算法13//  
             //演算法14//
         }
     }
 }

Void E()
 {
     //更改畫面欄位和收尾
     //演算法1//
     //設定1//
     //演算法2//
     //演算法3//
 }

//////////////////////////////////////////////////////////

//剛剛那段程式可改成
 A();
 B();
 D();
 E();

//////////////////////////////////////////////////////////////

呼,有沒有乾淨很多,通常在趕時或者您是初學者(包括沒寫過很多程式的人),一般還是回寫成像第一步那樣(包括我,因為有時候非常趕),您太早分很多函式,其實你程式碼會跳來跳去,有時候不方便你寫演算法

所以啥時要將您的程式改成這樣,就要您自己評估了,總之改完後比較好維護,因為假設你主要程式有問題,您只需要去看B(),如果您設定或者讀取參數有問題,您只需去看AE

這只是物件導向最簡單的物件化方式(模組化,介面化都是一樣的意思啦),當然實作你不一定要都寫成獨立函式,您也可以寫在class裡面或是namespace裡面,其實是一樣的意思

總之物件化的用途,就是讓您的東西各自獨立,方便管理,並且可以重新使用,您要是別的案子有用到,您就把其中一個函式複製過去就可以直接用了,例如您寫一個氣泡排序法,寫成函式後你就可以重複使用(reuse)

機車爺,排整齊排到吐血
四月份進度就到這,八月份再來嘴砲@3@8,希望真的可以掰五年XDㄏㄏㄏ