這部分是c++升級c的主要內容,也是c++的精髓部分,c是面向過程的,而C++是物件導向的。物件導向編程(OOP)的最重要特性有:
*抽象
*封裝和資料隱藏
*多態
*繼承
*代碼的可重用性
1.抽象和類:
C++中的類,是一種將抽象將抽象轉換為使用者定義型別的C++工具(其他物件導向語言也類似,如java),它將資料表示和操縱資料的方法組合成一個整
潔的包。
定義類的規範有兩個部分:類聲明和類方法定義。
類聲明:以資料成員的方式描述資料部分,以成員函數(也成為方法)的方式描述公有介面。
類方法定義:描述如何?類成員函數。
簡單地說就是,類聲明提供了類的藍圖,而類的方法定義則提供了實現細節。
對類成員的控制訪問:由於隱藏資料時oop的主要目標之一,所以資料項目通常放在私人部分(private),組成類介面的成員函數放在公有部分,否則就無
法從程式中調用這些函數,一般使用私人成員函數來處理不屬於公用介面的實現細節。有時候不必使用private關鍵字,因為C++中,private是類對象預設
存取控制。
現在學了類了,對類和結構的區別有了更進一步的瞭解:實際上類是對結構的擴充,他們有很多的相同特性,唯一區別是,結構的預設存取控制室public,
類是private的。注意:結構體也可以定義方法:例如如下:
public struct Person
{
string name;
double height;
double weight;
public void OverWeight()
{
.....
}
}
成員函數的定義:與常規函數定義非常相似,但是有兩個特色的特徵:
(1)定義成員函數是,使用範圍解析操作符(::)來標識函數所屬的類
(2)類方法可以訪問類的private組件
程式碼範例:
#include<iostream>
#include<cstring>
using namespace std;
//類聲明
class Stock
{
private:
char company[30];//公司名稱
int shares;//所持股票的數量
double share_val;//每股的價格
double total_val;//股票總值
void SetTol()//這是個內陸函數
{
total_val=shares*share_val;
}
public:
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();//顯示關於所持股票的資訊
};
//定義類的成員函數
void Stock::Acquire(const char *co,int n,double pr)
{
strncpy(company,co,29);
company[29]='\0';
if(n<0)
{
cerr <<"股票數量不能為負的!"<<endl;
cerr <<company<<"的股票數量設定為0"<<endl;
shares = 0;
}
else
shares = n;
share_val = pr;
SetTol();
}
void Stock::Buy(int num,double price)
{
if(num<0)
{
cerr<<"增持股票數量不能為負的!"<<endl;
}
else
{
shares +=num;
share_val=price;
SetTol();
}
}
void Stock::Sell(int num,price)
{
if(num<0)
{
cerr<<"賣出股票數量不能為負的!"<<endl;
}
if(num>shares)
{
cerr<<"你賣出的股票數量不能大於你所持有的數量"<<endl;
}
else
{
shares = shares - num;
share_val=price;
SetTol();
}
}
void Stock::Update(double price)
{
share_val=price;
SetTol();
}
void Stock::Show()
{
cout <<"company: "<<company;
cout <<" shares: "<<shares<<endl;
cout <<"share price:$"<<share_val;
cout <<"total Worth:$"<<total_val<<endl;
}
cerr對象:和cout對象一樣,也是一個ostream對象,之間的區別在於,作業系統重新導向隻影響cout,而不影響cerr。cerr對象用於錯誤資訊
內聯方法:在類聲明中定義的的函數都將自動成為內嵌函式。因此以上SetTol()函數就是內嵌函式
注意:調用成員函數時,它將使用被用來調用它的對象的成員資料。所建立的對象都有自己的儲存空間,用於儲存其內部變數和類成員;但同一個累的 所有對象共用同一組類方法,集每個方法(函數)只有一個副本。
2.類的建構函式和解構函式:
建構函式:是建立對象是自動調用的,但是不能通過對象來調用建構函式。還有就是不能將類成員名稱用作建構函式的參數!
解構函式:用建構函式建立對象後,程式負責跟蹤該對象,直到其到期為止。對象到期時,程式將自動調用一個特殊的函數來完成清理工作,這個函數就是解構函式
程式碼範例:
stock.h檔案代碼:
#include<iostream>
#include<cstring>
using namespace std;
//類聲明
class Stock
{
private:
char company[30];//公司名稱
int shares;//所持股票的數量
double share_val;//每股的價格
double total_val;//股票總值
void SetTol()//這是個內陸函數
{
total_val=shares*share_val;
}
public:
Stock();
Stock(const char *co,int n,double pr);
~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();//顯示關於所持股票的資訊
};
stock.cpp檔案代碼:
#include<iostream>
#include<cstring>
#include"stock.h"
using namespace std;
//類的實現
//定義類的成員函數
Stock::Stock()//預設建構函式
{
cout<<"Default constructor called:"<<endl;
strcpy(company,"noname");
shares=0;
share_val=0.0;
total_val=0.0;
}
Stock::Stock(const char *co ,int n,double pr)//建構函式
{
cout<<"Constructor using:"<<endl;
strncpy(company,co,29);
company[29]='\0';
if(n<0)
{
cerr <<"股票數量不能為負的!"<<endl;
cerr <<company<<"的股票數量設定為0"<<endl;
shares = 0;
}
else
shares = n;
share_val = pr;
SetTol();
}
Stock::~Stock()//解構函式
{
cout<<"bye, "<<company<<"!"<<endl;//輸出只是為了瞭解什麼時候解構函式被調用。
}
void Stock::Buy(int num,double price)
{
if(num<0)
{
cerr<<"增持股票數量不能為負的!"<<endl;
}
else
{
shares +=num;
share_val=price;
SetTol();
}
}
void Stock::Show()
{
cout <<"company: "<<company;
cout <<" shares: "<<shares<<endl;
cout <<"share price:$"<<share_val;
cout <<" total Worth:$"<<total_val<<endl;
cout <<endl;
}
main.cpp檔案代碼:
#include <cstdlib>
#include <iostream>
#include<cstring>
#include"stock.h"
using namespace std;
int main(int argc, char *argv[])
{
cout.setf(ios_base::fixed);//格式化
cout.precision(2);//格式化
cout.setf(ios_base::showpoint);//格式化
cout<<"Using constructor to new objects:"<<endl;
Stock stock1("NanoSmart",12,20.0);
stock1.Show();
Stock stock2=Stock("Boffo Objects",2,2.0);
stock2.Show();
cout<<"Assigning stock1 to stock2:"<<endl;
stock2=stock1;
cout<<"Listing stock1 and stock2:"<<endl;
stock1.Show();
stock2.Show();
cout<<"Using a constructor to reset an object:"<<endl;
stock1=Stock("Nifty Food",10,50.0);
cout<<"Revised stock1:"<<endl;
stock1.Show();
cout<<"Done\n";
return 0;
}
以上三個檔案編譯串連運行後的結果如下:
想想結果為什麼會這樣??
const 成員函數:將const放在類函數之後,如 void Show()const,這樣定義就是const成員函數,一般情況下,只要類方法不修改對象,則就應該將其聲明為const。
建構函式的特例:接受一個參數的建構函式允許使用賦值句法來將對象初始化一個值,如建構函式原型為:Bob(int age);
則可以這樣初始化:Bob czm=22;這是第三種初始化對象的方法。
3.this指標:指向用來調用成員函數的對象(this被作為隱藏參數傳遞給方法)。每個成員函數(包括建構函式和解構函式)都有一個this指標,this指標指向調用對象,this也是一個指標,所以和一般的指標一樣,*this指標指向的值。
程式碼範例:
const Stock& Stock::Topval(const Stock & s) const
{
if (s.total_val>total_val)
return s;
else
return *this;
}
4.對象數組:要建立類對象數組,這個類必須有預設建構函式。因為初始化對象數組時,首先使用預設建構函式建立數組元素,然後花括弧中的建構函式將建立臨時變數,然後將臨時變數的內容複寫到相應的元素中。如:Stock stk[4] = {Stock("caizhiming",2,20),Stock("caizhicong"),Stock("caizhiming2",333,34),};
現在對this指標比較瞭解了,現在深入瞭解C++的工作方式,比如C++前端cfront將c++程式轉換為c程式:處理方法的定義時,只需將下面C++的定義:
void Stock::Show()const
{
cout <<"company: "<<company;
cout <<" shares: "<<shares<<endl;
cout <<"share price:$"<<share_val;
cout <<" total Worth:$"<<total_val<<endl;
}
轉換為類C風格的定義:
void Show(const Stock *this)
{
cout <<"company: "<<this->company;
cout <<" shares: "<<this->shares<<"\n";
cout <<"share price:$"<<this->share_val;
cout <<" total Worth:$"<<this->total_val<<"\n";
}
同樣的,將top.Show()轉換為Show(&top)
5.小結:
物件導向編程強調的是程式如何表示資料。類是使用者定義的類型,而對象則是類的執行個體,即對象是這種類型的變數。如果希望成員函數對多個對象進行操作,則可以將額外的對象作為參數傳遞給它。如果方法需要顯示的引用調用它的對象,則可以使用this指標。