C++學習之----;類

http://210.44.195.12/cgyy/text/HTML/text/20.htm 

 

 

類:

 類申明:以數據成員的方式描述數據部分,以成員函數(被稱爲方法)的方式描述公有接口。

類方法定義:描述如何實現類成員函數。

簡單的說:類聲明提供了類的藍圖,而方法定義則提供了細節。

 

使用類,必須瞭解公共接口,編寫類,必須創建公共接口。

 

控制成員訪問:公有還是私有

   無論類成員是數據還是成員函數,都可以在類的共有或私有部分中聲明,但是由於隱藏數據是OOP的主要目標之一,因此,數據項通常放在私有部分,組成類接口的成員函數放在公有部分。

類的定義:

   定義成員函數時:使用作用域解析操作符::來標識函數所屬的類;

   類方法可有訪問類的private組建。

 

注意:調用成員函數時,它將使用被用來調用它的對象的數據成員。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

可以說這是一個面向對象編程的最基本的問題。我不想引進一大堆的慨念。這裏只打一個形象的比方。
    類其實就是一輛已裝配好的自行車,自行車在基本組成方面有前後輪,坐椅,後坐,腳登板,方向盤等,在功能方面有腳登板,前後輪,方向盤的 轉動和自行車的移動等;在這裏,前後輪,坐椅,後坐,腳登板,方向盤就是類的數據成員,數據成員有私有的(private),保護的 (protected),公有的(public);前後輪就是類的私有數據成員(因爲它不可以被外界訪問),坐椅,後坐,腳登板,方向盤就是類的公有的數 據成員(因爲它可以被外界訪問);
    類裏負責操縱數據成員或提供一些功能的函數就是類的成員函數。在這裏,腳登板,前後輪,方向盤的轉動和自行車的移動功能就是類的成員函 數。類還有友元類,一個友元類可以訪問類的私有數據,而非友元類則不能訪問類的私有數據,這就實現了類的封裝(就象包裝好的自行車一樣)。類可以派生,現 在你想造一輛能用馬力拉的又具有自行車
    特徵的機器,這個機器就是自行車的派生類,它繼承了自行車的一切特徵但又具有一些擴展的功能,派生類可以訪問父類的數據成員,重載父類的成員函數,實現父類虛函數的功能等。好了,就說到這吧,將得不好,別見笑,有錯誤的話請指正。

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

#include <iostream>
#include <cstring>
using namespace std;
 

  class Stock  //class declaration
    {
       private:
          char company[30];
          int shares;
          double share_val;
          double total_val;
          void set_tot(){ total_val=shares*share_val;}
       public:
         // Stock();
          void acquire(const char *co,int n,double pr);
          void buy ( int num, double price);
          void sell (int num, double price);
          void update ( double price);
          void show();
    };  //note semicolon at the end;
   
   
    void Stock::acquire(const char * co,int n,double pr)
          {
            strncpy(company, co, 29);  //truncate co to fit company;
            company[29] = '/0';
          if (n <0)
                 {
                   cerr << "Number of shares can't be negative." << company
                        << " shares set to 0. /n";
                         shares =0;
                  }
               else 
                   shares = n;
                   share_val =pr;
                   set_tot();
               
            }
     void Stock::buy(int num,double price)
          {
            if (num <0)
                {
                  cerr << "Number or shares purchased can't be negative. "
                       << "Transaction is aborted./n";  
                }
            else
                {
                   shares += num;
                   share_val = price;
                   set_tot();
                }   
          }    
     void Stock::sell(int num, double price)
          {
            using std::cerr;
            if (num<0)
               {
                  cerr <<" Number of shares sold can't be negative."
                       << "Transaction is aborted./n";
               }
            else if (num > shares)
                {
                    cerr << "You can't sell more than you have!"
                        << "Transaction is aborted./n";
                }
            else
                {
                  shares -=num;
                  share_val = price;
                  set_tot();
                }
          } 
     void Stock::update(double price)
          {
              share_val =price;
              set_tot();
           }
     void Stock::show()
          {
            cout << "Company: " << company << "  shares:" << shares <<endl
                 << " share price:  $" << share_val
                 << " Total worth:$" << total_val << endl;
          }

    int main()
        {
           Stock stock1;
           stock1.acquire("NanoSmart", 20, 12.5);
           cout.setf(ios_base::fixed);
           cout.precision(2);
           cout.setf(ios_base::showpoint);
           stock1.show();
           stock1.buy(15,18.25);
           stock1.show();
           stock1.sell(400,22.00);
           stock1.show();
           return 0;
        }

 

 

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

函數模板

    函數的重載可以實現一個函數名多用,將實現相同的或類似功能的函數用同一個函數名 來定義。這樣可以使編程者在調用同類函數時感到含義清楚,方法簡單。但是在程序中仍然要分別定義每一個函數,如例1.6的程序中三個max函數的函數體是 完全相同的,只是形參的類型不同,也要分別定義。有些讀者自然會想到,對此能否再簡化呢?
    爲了解決這個問題,C++提供了函數模板(function template)。所謂函數模板,實際上是建立一個通用函數,其函數類型和形參類型不具體指定,用一個虛擬的類型來代表。這個通用函數就稱爲函數模板。 凡是函數體相同的函數都可以用這個模板來代替,不必定義多個函數,只須在模板中定義一次即可。在調用函數時系統會根據實參的類型來取代模板中的虛擬類型, 從而實現了不同函數的功能。

例8 將例6中的程序改爲通過函數模板來實現。

#include<iostream>
using namespace std;
template<typename T>; //模板聲明,其中T爲類型參數
T max(T a,T b,T c)   //定義一個通用函數,用T作虛擬的類型名
{ if(b>a)a;b:
  if(c>a)a:c;
   return a:
}
int main()
{ int i1=8,i2=5,i3=6,i;
  double dl=56.9,d2=90.765,d3=43.1,d;
   long g1=67843,g2=-456,g3=78123,g;
   i=max(i1,i2,i3);     //調用模板函數,此時T被int取代
   d=max(d1,d2,d3);    //調用模板函數,此時T被double取代
   g=max(8l,S2,83);    //調用模板函數,此時T被long取代
   cout <<"i_max="<<i <<endl;
   cout<<"f_max="<< f << endl;
   cout<< "g_max="<<g <<endl;
   return ();}

 

 

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


#include <iostream>
using namespace std;

template <typename T>
T max(T a,T b, T c)
  {
    a=a>b?a:b;
    a=a>c?a:c;
    return a;
  }



int main(int argc, char** argv)

    int i1=8,i2=5,i3=6,i;
    double d1=56.9,d2=90.88,d3=1029.77,d;
    long g1=33333,g2=76865656,g3=6789,g;
    i=max(i1,i2,i3);
    d=max(d1,d2,d3);
    g=max(g1,g2,g3);
    cout << "i_max=" << i << endl;
    cout << "f_max=" << d << endl;
    cout << "g_max=" << g << endl;
       
   
    return 0;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    運行結果與例6相同。爲了節省篇幅,數據不用cin語句輸入,而在變量定義時初始化。程序第3-8行是定義模板。定義函數模板的一般形式爲
        template<typename T> 或template<class T>
通用函數定義 通用函數定義。
   
    class和typename的作用相同,都是表示“類型名”,二者可以互換。以前的C++程序員都用class。typename是不久前才被加到標準 C++中的,因爲用class容易與C++中的類混淆。而用typename其含義就很清楚,肯定是類型名(而不是類名)。
    可能對模板中通用函數的表示方法不習慣,其實在建立函數模板時,只要將例6程序中定義的第一個函數首部的int改爲T即可。即用虛擬的類型名T代替具體的 數據類型。在對程序進行編譯時,遇到第13行調用函數max(i1,i2,i3),編譯系統會將函數名max與模板max相匹配,將實參的類型取代函數模 板中的虛擬類型T。此時相當於已定義了一個函數:
        int max(int a,int b,int c)
        { if(b>a) a=b;
          if(c>a) a=c;
          return a;
        }
然後調用它。後面兩行(14,15行)的情況類似。 類型參數可以不只一個,可根據需要確定個數。如
    template<class T1,typename T2>
    可以看到,用函數模板比函數重載更方便,程序更簡潔。但應注意它只適用於函數的參數個數相同而類型不同,且函數體相同的情況,如果參數的個數不同,則不能用函數模板。

發佈了39 篇原創文章 · 獲贊 7 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章