l 指向常量的指針。
Inta;
Const int *p1 = &a; //p1是指向常量的指針
Intb;
P1= &b; //正確,p1本身的值可以改變
P1= 1; //編譯錯誤,不能通過p1改變所指對象的值
l 指針類型的常量。
Int * const p2 = &a;
P2&b; //錯誤,p2是指針常量,值不能改變
l void類型指針可以存儲任意類型的對象地址。
l 0專用于表示空指針,也就是一個不指向任何有效地址的指針。
Int *p; //聲明一個int型指針p。
P = 0; //將p設置為空指針,不指向任何地址。
? 細節:空指針也可以用NULL來表示,NULL是一個在很多頭文件中都有
定義的宏,被定義為0。
l 復制構造函數
復制構造函數是一種特殊的構造函數,具有一般構造函數的所有特征,其形
參是本類的對象的引用。其作用是使用一個已經存在的對象(由復制構造函數的參數指定),去初始化同類的一個新對象。
下面是聲明和實現復制構造函數的一般方法:
Class類名
{
Public:
類名(形參表); //構造函數
類名(類名 &對象名); //復制構造函數
}
類名::類名(類名 &對象名) //復制構造函數的實現
{ 函數體
}
復制構造函數在下面三種情況中會被調用:
1. 當用類的一個對象去初始化該類的另一個對象時:
Intmain()
{
Point a(1, 2);
Point b(a); //用對象a初始化對象b,復制構造函數被調用
Point c = a; //用對象a初始化對象c,復制構造函數被調用
Cout<<b.getX()<<endl;
Return 0;
}
2. 如果函數的形參是類的對象,調用函數時,進行形參和實參結合時:
Voidf(Point p)
{
Cout<<p.getX()<<endl;
}
Intmain()
{
Point a(1, 2);
f(a); //函數的形參為類的對象,當調用函數時,復制構造函數調用
return 0;
}
3. 如果函數的返回值是類的對象,函數執行完成返回調用者時:
Point g(){
Point a(1, 2);
returna;
}
Int main() {
Point b;
//函數的返回值是類的對象,返回函數值時,調用復制構造函數
b = g();
return 0;
}
l 友元關系提供了不同類或對象的成員函數之間、類的成員函數與一般函數之
間進行數據共享機制。通俗地說,友元關系就是一個類主動聲明哪些其他類或者函數是它的朋友,進而給他們提供對本類的訪問特許。
1. 友元函數
友元函數是在類中用關鍵字friend修飾的非成員函數。友元函數可以是一個
普通的函數,也可以是其他類的成員函數。雖然它不是本類的成員函數,但是在它的函數體中可以通過對象名訪問類的私有和保護成員。
2. 友元類
同友元函數一樣,一個類可以將另一個類聲明為友元關系。若A類為B類的
友元類,則A類的所有成員函數都是B類的友元函數,都可以訪問B類的私有和保護成員。聲明友元類的語法形式為:
Class B
{
… //B類的成員聲明
Friend class A //聲明A為B的友元類
}
l 虛基類
虛基類的聲明是在派生類的定義過程中進行的,其語法形式為:
Class 派生類名::virtual 繼承方式 基類名
在多繼承情況下,虛基類關鍵字的作用范圍和繼承方式關鍵字相同,只對緊跟其后的基類起作用。聲明了虛基類之后,虛基類的成員在進一步派生過程和派生類一起維護同一個內存數據副本。
l 訪問控制
1. 公有繼承
當類的繼承方式為公有繼承時,基類的公有成員和保護的訪問屬性在派生類
中不變,而基類的私有成員不可直接訪問。
2. 私有繼承
當類的繼承方式為私有繼承時,基類的公有成員和保護成員都以私有身份出
現在派生類中,而基類的私有成員在派生類中不可直接訪問。
3. 保護繼承
保護繼承中,基類的公有成員和保護成員都以保護成員的身份出現在派生類
中,而基類的私有成員不可直接訪問。
l 運算符重載
運算符的重載有兩種形式,即重載為類的非靜態成員函數和重載為非成員
函數。運算符重載為類的成員函數的一般語法形式:
返回類型 Operator 運算符(形參表)
{
函數體
}
運算符重載為非成員函數的一般語法形式:
返回類型 operator 運算符(形參表)
{
函數體
}
返回類型指定了重載運算符的返回值類型,也就是運算符結果類型;operator是定義運算符重載的關鍵字;運算符即是要重載的運算符名稱,必須是C++中可重載的運算符,比如要重載加法運算符,這里就寫+;形參表中給出重載運算符所需要的參數和類型。
l 虛函數
一般虛函數成員的聲明語法是:
virtual 函數類型函數名(形參表);
這實際上就是在類的定義中使用virtual關鍵字來限定成員函數,虛函數聲
明只能出現在類定義中的函數原型聲明中,而不能在成員函數實現的時候。
運行過程中的多態需要滿足3個條件,第一是類之間滿足賦值兼容規則,第二是要聲明虛函數,第三是要由成員函數來調用或者是通過指針、引用來訪問虛函數。
l 純虛函數和抽象類
純虛函數的聲明格式:
virtual 函數類型函數名(參數表)=0;
實際上,它與一般虛函數成員的原型在書寫格式上的不同就在于在后面加了”=0”。聲明為純虛函數之后,基類中就可以不再給出函數的實現部分。純虛函數的函數體由派生類給出。
帶有純虛函數的類是抽象類。抽象類的主要作用是通過它來為一個類族建立一個公共的接口,使它能夠更有效地發揮多態特性。
抽象類不能實例化,即不能定義一個抽象類的對象,但是可以定義一個抽象類的指針和引用。
l 函數模板與類模板
所謂參數化多態性,就是將程序所處理的對象的類型參數化,使得一段程
序可以用于處理多種不同類型的對象。
函數模板的定義形式是:
template 函數名(參數表)
{
函數體的定義
}
使用類模板使用戶可以為類定義一種模式,使得類中的某些數據成員、某些成員函數的參數,返回值或局部變量能取任意類型(包括系統預定義的和用戶自定義的)。
類模板聲明的語法形式是:
Template <模板參數表>
Class 類名
{
類成員聲明
}
如果需要在類模板以外定義其成員函數,則要采用以下的形式:
Template<模板參數表>
類型名類名<模板參數標識符列表>::函數名(參數表)
一個類模板聲明自身并不是一個類,它說明了類的一個家族。只有當被其他代碼引用時,模板才根據引用的需要生成具體得類。使用一個模板類來建立對象是,應該按如下格式聲明:
模板名<模板參數表> 對象名1,…,對象名n;
l 泛型程序設計的基本概念
我們可以用概念(concept)來描述泛型程序設計中作為參數的數據所需具備
的功能。這里的“概念”是泛型程序設計的一個術語,它的內涵是這些功能,它的外延是具有這些功能的所有數據類型。例如:“可以用比大小、具備公有復制構造函數并可以用‘=’賦值的所有數據類型”就是一個概念,可以把這個概念記作Sortable。具備一個概念所需要功能的數據類型稱為這一概念的模型(model)。例如int數據類型就是Sortable概念的一個模型。對于兩個不同的概念A和B。如果概念A所需求的所有功能也是概念B所需求的功能(即概念B的模型一定是概念A的模型),那么就說概念B是概念A的子模型。我們把”可以比大小的所有數據類型”這一概念記為Comparable,那么Sortable就是Comparable的子概念。
l 適配器
適配器(adapter)是指用于為已有對象提供新的接口的對象,適配器本身一般
并不提供新的功能,只是為了改變對象的接口而存在。
l Typeid
typeid用于返回指針或引用所指對象的實際類型。注意:typeid是操作符,
不是函數! 運行時獲知變量類型名稱,可以使用 typeid(變量).name(),需要注意不是所有編譯器都輸出"int"、"float"等之類的名稱,對于這類的編譯器可以這樣使用:float f = 1.1f; if(typeid(f) == typeid(0.0f) )。
l STL簡介
標準模板庫(Standard Template Library,STL)最初是由HP公司的Alexander
Stepanov和MengLee開發的一個用于支持C++泛型編程的模板庫,1994年被納入了C++標準,成為C++標準庫的一部分。
STL四種基本組件:
1.容器(container)
容器是容納、包含一組元素的對象。容器類庫中包括7種基本容器:向量(vector)、雙端隊列(depue)、列表(list)、集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。這7種容器可以分為兩種基本類型:順序容器(sequence container)和關聯容器(associative container)。順序容器將一組具有相同類型的元素以嚴格的線性形式組織起來,向量、雙端隊列和列表容器就屬于這一種。關聯容器具有根據一組索引來快速提取元素的能力,集合和映射容器就屬于這一種。
2.迭代器(iterator)
迭代器提供了順序訪問容器中每一個元素的方法。對迭代器可以使用”++”運算符來獲取指向下一個元素的迭代器,可以使用”*”運算符訪問一個迭代器所指向的元素。
3.函數對象(functionobject)
函數對象是一個行為類似函數的對象,對它可以像調用函數一樣調用。任何普通的函數和任何重載了”()”運算符的類的對象都可以作為函數對象使用,函數對象是范化的函數。
4.算法(algorithm)
STL包含70多個算法,這些算法覆蓋了相當大的應用領域,其中包括查找算法、排序算法、消除算法、計數算法、比較算法、變換算法、置換算法和容器管理等。這些算法的一個最重要的特征就是它們的統一性,并且可以廣泛用于不同的對象和內置的數據類型。
l STL中3種順序容器的特性比較
操作 | 向量(vector) | 雙端隊列(deque) | 列表(list) |
隨機訪問 | 快 | 較慢 | 不能 |
頭部插入 (push_front) | 沒有push_front 只能用insert完成 | 快 已有的迭代器失效,指針、引用不會失效 | 快 已有的迭代器、指針、引用都不會失效 |
頭部刪除 (push_back) | 沒有push_back 只能用erase完成 | 快 只會使被刪除元素的 迭代器、指針、引用失效 | |
尾部插入 (push_back) | 快 當發生容器擴展時,會使所有已有的迭代器、指針、引用失效; 否則不會使任何已有迭代器、指針、引用受到影響。 | 快 已有的迭代器失效,指針、引用不會失效 | 快 已有的迭代器、指針、引用都不會失效 |
尾部刪除 (pop_back) | 快 只會使被刪除元素的迭代器、指針、引用失效 | ||
任意位置 插入(insert) | 插入位置越接近頭部越慢。當發生容器擴展時,會使所有迭代器、指針、引用失效,否則只會使插入位置之后的迭代器、指針、引用失效 | 位置越接近中間越慢。
會使所有的迭代器、指針、引用失效 | 快 已有的迭代器、指針、引用都不會失效 |
任意位置 刪除(erase) | 刪除位置越接近頭部越慢。只會使刪除位置之后的迭代器、指針、引用失效 | 快 只會使被刪除元素的迭代器、指針、引用失效 |
新聞熱點
疑難解答
圖片精選