對象 object
算法
|--屬性 attribute編程
|--行爲 behaviour數組
調用對象中的函數就是向該對象傳送一個消息 message數據結構
封裝性 encapsulation框架
|--一是將有關數據和操做代碼封裝在一個對象中,造成一個基本單位,各個對象之間相對獨立,互不干擾函數
|--二是將對象中某些部分對外隱藏,即隱藏其內部細節,只留下少許接口,以便與外界聯繫,接受外界的消息,即信息隱藏 information hiding工具
抽象 abstractionthis
抽象的做用是表示同一類事物的本質。 類spa
繼承與重用指針
軟件重用 software reusability
多態性 polymorphism
面向過程:程序 = 數據結構 + 算法
面向對象:程序 = 對象s + 消息
—————————————————————————————————————
類class
類是對象的抽象,對象是類的具體實例(instance)
類頭 class head
類體 class body
成員列表 class member list
類中成員默認是private
struct成員默認是public
class 類名
{
private:
私有數據和成員函數
public:
公用數據和成員函數
};
成員訪問限定符 member access specifier
|--私有的 private 只能本類和友元類訪問
|--共有的 public 開放訪問
|--受保護的 protected 包括private屬性和派生類訪問
定義對象的方法:
類名 對象名;
Student stud1,stud2;此時爲對象分配存儲空間(Java中此語句的做用不一樣)
——————————————————————————————————————
類的成員函數
工具函數 utility function :只被本類中的成員函數調用,private
在類外定義成員函數
:: 做用域限定符,指明此函數屬於哪一個類
———————————————————————————————————————
對象成員的引用
三種方式:
|--成員運算符
對象名.成員名
|--指針
Time t, *p; p=&t; p->hour;
|--引用
Time t1;
Time &t2 = t1;
t2.hour;
默認參數:函數聲明的默認參數覆蓋定義時的默認參數
——————————————————————————————————————
類的封裝性和信息隱藏
公用接口 public interface
私有實現 private implementatioon
類的公用接口與私有實現的分離 稱爲 信息隱藏
軟件工程的一個基本原則:接口與實現相分離
當接口與實現分離時,只要類的接口沒有改變,對私有實現的修改不會影響程序的其餘部分
類聲明和成員函數定義的分離
實際工做中,將若干個經常使用的功能相近的類聲明集中在一塊兒,造成類庫。
類庫的組成:
|--類聲明頭文件
|--已經編譯過的成員函數的定義,它是目標文件
類庫有兩種:
|--標準類庫
|--自定義類庫
類聲明頭文件成爲用戶使用類庫的有效方法和公用接口
包含成員函數定義的文件就是類的實現
類聲明和函數定義分別放在兩個文件中
stud.display();
stud 對象
display() 方法
stud.display(); 消息
——————————————————————————————————————
類的數據成員不能在聲明類時初始化
構造函數 constructor 處理對象的初始化
創建對象是自動調用構造函數
帶參數的構造函數
構造函數名(類型1 形參1, 類型2 形參2,...)
類名 對象名(實參1,實參2,...)
參數初始化表
在函數首部實現初始化,能夠在類體中定義構造函數
Box::Box(int h, int w, int len):hight(h),width(w),length(len){ }
構造函數的重載
無參構造函數稱爲默認構造函數(default constructor) /缺省構造函數
一個類只能有一個默認構造函數
Box box1; //調用無參構造函數
Box box1(); //聲明一個函數,無參,返回類型爲Box
默認構造函數
在聲明構造函數時指定默認值,此時形參能夠省略
Box(int=10; int=10; int=10);
此時提供0 1 2 3個參數都可行,此時與函數重載矛盾
不能同時使用 構造函數的重載 和 有默認參數的構造函數。
——————————————————————————————————————
析構函數 destructor
對象生命週期結束時自動執行析構函數 在類名前加一個~
做用不是刪除對象,而是在撤銷對象佔用的內存以前完成一些清理工做,使這部份內存能夠被程序分配給新對象使用
析構函數不能重載
做用:
|--釋放資源
|--執行最後一次使用對象以後欲執行的任何操做
先構造後析構 後構造先析構 棧 針對同一存儲類別
—————————————————————————————————————
對象數組
Box a[3] = {
Box(10,12,15),
Box(15,18,20),
Box(16,20,26),
};
———————————————————————————————————————
指向對象成員函數的指針
數據類型名(類名::*指針變量名)(參數列表)
指針變量名=&類名::成員函數名
void (Time::*p)(); //聲明指針
p=&Time::get_time; //指針賦值 void (Time::*p) = &Time::get_time;
(t1.*p)(); //函數調用
———————————————————————————————————————
this指針
每一個成員函數都包含this指針,指向本類對象
其值是當前被調用的成員函數所在的對象的起始地址
this指針是隱式使用的,做爲參數被傳遞給成員函數
——————————————————————————————————————
公用數據的保護:
|--常對象 Time const t1(12, 34, 46);
|--常對象成員
|--常數據成員 const int hour;
|--常成員函數 void get_time( ) const; void Time::get_time( ){ }
|--指向對象的常指針 Time * const p = &t;
|--指向常對象的指針 const Time *p = &t;
|--對象的常引用 const Time &t = t1;
常對象
const 類名 對象名(形參列表)
const Time t1(10,15,36);
做用:將全部數據成員變爲const
限制:全部數據成員的值不能修改
不能調用非const型的成員函數
mutable int count; //被mutable修飾的數據成員能夠用聲明爲const的成員函數修改
常對象成員
|--常數據成員:
只能經過構造函數的參數初始化表對常數據成員進行初始化,其值不能改變
|--常成員函數:
只能引用本類中的數據成員,而不能修改它們
聲明和定義後面都加const,調用時不加
常成員函數不能調用另外一個非const成員函數
指向對象的常指針
類名 * const 指針變量名 = 對象地址;
指向始終不變 必須在定義時初始化
用常指針做爲函數的形參,使其在函數執行過程當中指針始終指向不變對象。
指向常變量的指針
const 類型名 * 指針變量
常變量只能被指向常變量指針指向
普通變量既能夠被普通指針指向,也能夠被指向常變量指針指向(此時其值不能修改)
普通指針 指向常變量指針
普通變量 1 1
常變量 0 1
指向常對象的指針
const 類名 * 指針變量
普通指針 指向常對象指針
普通對象 1 1
常對象 0 1
指向常對象的指針最經常使用於函數的形參,目的在於保護形參指針所指向的對象在函數執行過程當中不被修改
當但願在調用函數時對象的值不被修改,則把形參定義爲指向常對象的指針;
若是但願對象的值在程序執行過程當中不被修改,則把其定義爲常對象。
對象的常引用
const Time &t;//不能修改t所引用的對象
常常用常指針和常引用做爲函數參數
一、數據不能被修改
二、沒必要創建實參拷貝
———————————————————————————————————————
對象的動態創建和釋放
經過指針操做
Box * pt;
pt = new Box(12,15,18);
pt->height; //動態對象經過指針訪問,主要用於動態數據結構,如鏈表
delete pt; //調用析構函數,釋放內存
——————————————————————————————————————
對象的賦值和複製
對象的賦值:
對象1 = 對象2;//兩者屬於同一個類 = 運算符重載
//實現:成員複製 memberwise copy
//只針對數據成員,不能有動態分配的數據
對象的複製
Box box2(box1),//用已有對象box1去克隆出一個新對象box2
原理:複製構造函數 copy constructor 系統默認提供
Box::Box(const Box &b)
{
height=b.height;
width=b.width;
lenth=b.length;
}
另外一種形式:
類名 對象名1 = 對象名2;
Box box2 = box1;
Box box2 = box1, box3 = box2;//用box1建立新的box2,用box2建立新的box3
須要對象複製的狀況:
須要用一個已經存在的對象,創建一個新的對象
函數的參數爲類的對象
函數返回值是類的對象
————————————————————————————————————
靜態成員 在同類的多個對象之間實現數據共享
靜態數據成員
以關鍵字static開頭
靜態數據成員在內存中只佔一份空間
靜態數據成員在全部對象以外單獨開闢空間
靜態數據成員屬於類,能夠經過類名::引用
編譯時分配,程序結束後釋放
靜態數據成員的初始化只能在類體外進行初始化
int Box::height = 10;
數據類型 類名::靜態數據成員 = 初值;
如未賦初值,自動賦值爲0
靜態成員函數
和普通函數本質區別:沒有this指針
目的:處理靜態數據成員
——————————————————————————————————————
友元 關鍵字friend
目的:訪問類的私有成員
友元能夠訪問與其有好友關係的類中的私有成員
種類:
|--友元函數
|--普通函數
|--友元成員函數
|--友元類
有一函數,在類體中用friend對該函數進行聲明,此函數就稱爲本類的友元函數
普通友元函數:
class Time
{
public:
friend void display(Time &); //進行友元函數聲明
}
void display (Time &t)
{對t進行訪問}
友元成員函數 步驟不能亂
class Date; //對Date類的提早引用聲明
class Time
{
public:
void display(Date &); //此函數欲訪問Date的私有成員
}
class Date
{
public:
friend void Time::display(Date &); //聲明Time類中的display函數爲本類的友元成員函數
}
void Time::display(Date &d)
{對d進行訪問}
提早引用聲明:在正式聲明一個類以前,先聲明一個類名,表示此類將在稍後聲明。
提早引用聲明以後,能夠定義指針和引用
正式聲明以後,才能夠定義對象
一個函數(包括普通函數和成員函數)能夠被多個類聲明爲「朋友」,這樣就能夠引用多個類中的私有數據
友元類
B類是A類的友元類:B類的函數都是A類的友元函數
通常形式:
friend 類名;
特色:
單向
不傳遞
弊:對封裝原則的小破壞
利:數據共享,提升程序效率
關鍵:數據共享 與 信息隱藏 之間選擇平衡
———————————————————————————————————————
類模板 template
可定義多個虛擬的類型參數
template<class 類型參數名>
template<class numtype>
class Compare
{ }; //類模板的定義 參數化的類
Compare <int> com(4,7); //對象的定義
類是對象的抽象
類模板是類的抽象
類模板外定義成員函數的形式:
template<class 虛擬函數類型>
函數類型 類模板名<虛擬類型參數>::成員函數名(函數形參列表){...}
—————————————————————————————————————
運算符重載
重載 overloading
函數重載:對一個已有的函數賦予新的含義,使之實現新的功能
一名多用
運算符重載 operator overloading
運算符重載的方法:
定義一個重載運算符的函數
運算符重載實質上是函數的重載
格式:
函數類型 operator 運算符名稱 (形參列表)
{ 對運算符的重載處理 }
Complex operator+(Complex &c1, Complex &c2);
operator是關鍵字
operator運算符 至關於 函數名
函數 operator+ 重載了運算符 +
重載運算符的規則:
一、只能對已有的C++運算符進行重載;
二、5個不能重載的運算符:
. 成員訪問運算符
.* 成員指針訪問運算符
:: 域運算符
sizeof 長度運算符
?: 條件運算符
三、不能改變操做數的個數
四、不能改變優先級
五、不能改變結合性
六、不能有默認的參數
七、參數至少有一個用戶自定義類對象或其引用
八、 = & 用於類對象時沒必要重載
九、重載運算符的功能應相似於該運算符做用於標準類型數據時所實現的功能
十、運算符重載函數能夠是類的成員函數、類的友元函數、普通函數(get方法,效率低)
重載單目運算符:成員函數
重載雙目運算符:友元函數
重載雙目運算符:
友元函數
先搭框架,逐步擴充,由簡到繁,最後完善
邊編程,邊調試,邊擴充
重載單目運算符:
成員函數
對於自增自減運算符:若是在運算符重載函數中,增長一個int型形參,就是後置自增自減運算符函數,
此int形參僅起到標誌做用
重載流插入運算符
istream& operator >> (istream&,自定義類&);
istream& operator << (ostream&,自定義類&);
只能將重載 >> 和 << 的函數做爲友元函數或普通函數,不能將它們定義爲成員函數
引用 reference 的重要性
一、函數形參是引用:減小時間和空間的開銷
二、返回對象是引用:能夠成爲左值 left value,能夠連續輸入輸出
——————————————————————————————————————
不一樣數據類型之間的轉換
標準數據類型的轉換
|--隱式轉換
|--顯示轉換 int(9.8) C++ (int)9.8 C
構造函數
|--默認構造函數Complex()
|--初始化構造函數 Complex(double r, double i)
|--複製構造函數Complex(Complex &)
|--轉換構造函數Complex(double r) //double 轉爲 Complex
轉換構造函數只有一個形參
應用:類名(指定類型的數據)
類型轉換函數 type conversion function
做用:將一個類對象轉換成另外一個類型的數據
應用: operator 類型名()
{實現轉換的語句}
//函數名不能有返回類型,不能有參數,只能做爲成員函數(不然沒法自動調用)
//函數名是 operator 類型名
當須要的時候,編譯系統自動調用 轉換構造函數、類型轉換函數(隱式調用)
類型轉換函數 轉換構造函數 的同時出現可能致使程序的二義性
c1 + 2.5 的兩種解釋
double(c1) + 2.5 返回傳統數據類型 類型轉換函數
c1 + Complex(2.5) 返回自定義類對象 轉換構造函數 + 運算符重載
故兩者不能同時出現