OOP特性:抽象,封裝和數據隱藏,多態,繼承,代碼的可重用性
函數重載(函數多態):設計一系列的函數完成相同的工作或者說可以使用多個同名的函數
函數重載的關鍵是:參數列表(函數特徵標)
類:
class Stock
{
private:
char company[30];
int shares;
double share_val;
double total_val;
void set_tot()
{
total_val = shares*share_val;
}
public:
void update(double price);
void show();
void buy(int num, double price);
};
一般來說,類有兩部分組成:
1.類聲明:以數據成員的方式描述數據部分,以成員函數的方式描述公有接口
2.類方法定義:描述如何實現類成員函數
關鍵字:Private:數據隱藏,是能通過Public內的成員函數訪問Private裏的成員。
Public:公開的
實現類成員函數:(兩個特殊的特徵)
1.定義成員函數時,使用作用域解析運算符(::)來標識函數所屬的類
2.類方法可以訪問類的Private組件
例如:
void Stock::Update(double price)
構造函數:
名稱與類名相同,雖然沒有返回值,但也沒有被聲明void類型(構造函數沒有聲明類型)
構造函數的參數名與成員名不要相同,否則會發生混亂。在程序聲明對象時,會自動調用構造函數
每次創建對象時(甚至使用new分配內存時,C++都使用類構造函數),構造函數與new一起使用的方法:
Stock *postock = new Stock("XX", ,);
顯式使用構造:
Stock food = Stock("XX", ,);
隱式使用構造:
Stock food(“XX”, ,);
一般來說:使用對象來調用方法,但無法調用構造函數,因爲構造函數時構造對象的
默認構造函數:未提供顯式初始值時,用來創建對象的構造函數。
默認構造函數沒有任何參數,如果有,則必須給所有參數提供默認值。
在創建對象時,如果沒有提供任何構造函數,則C++將會自動提供默認構造函數。
可能爲:
Stock::Stock(){}
定義默認構造函數的兩種方式:
1.給已有的構造函數的所有參數提供默認值
2.重載構造
Stock::Stock()
{
company = "no name";
shares = 0;
share_val = 0;
total_val = 0;
}
析構函數
析構函數:當對象過期時,程序會自動調用一個成員函數——析構函數(完成清理工作)
析構名稱:在類型名字前加~ 析構函數沒有返回值和聲明類型,本身也不承擔任何重要的功能
原型: ~Stock()
使用:
Stock::~Stock()
{
}
什麼時候使用析構呢? 由編譯器決定,通常不應在代碼中顯示調用
如果創建靜態存儲類對象:則其析構函數在程序結束後會自動調用
如果創建動態存儲類對象:則其析構函數會在程序執行完代碼塊時自動被調用
如果對象通過new定義的,則它駐留在棧內存或自由存儲區中,當使用delete釋放內存時,析構自動被調用
注:
Stock Stock2 = Stock("xx", , );
Stock1 = Stock("xx", , );
這兩條語句有根本性區別:
第一條語句是初始化,它創建有指定值的對象,可能會創建臨時對象,也可能不會創建。
第二條語句是賦值,在賦值之前一定會調用構造創建一個臨時對象,結束後調用析構。
如果可以既通過初始化,也可以通過賦值來設置對象的值,則應採用初始化方式(通常效率更高)。
C++11列表初始化,只要提供與某個構造函數的參數列表匹配的內容,並用大括號括起:
Stock jock = {"xx", , };
Const成員函數
const Stock land = Stock("xx", , );
land.show();
編譯器將拒絕第二行,因爲show()代碼無法保證調用對象不被修改。
以前通過將函數參數聲明爲const引用或指向const的指針來解決這種問題,但是show()方法沒有參數,這時需要一種特殊的語法。將const關鍵字放在函數的括號後面:
void show() const;
同樣,函數定義的開頭應該爲:
void Stock :: show() const;