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>
可以看到,用函數模板比函數重載更方便,程序更簡潔。但應注意它只適用於函數的參數個數相同而類型不同,且函數體相同的情況,如果參數的個數不同,則不能用函數模板。