C++支持多種編程范式 --面向對象編程、泛型編程和過程化編程。常用於系統開發,引擎開發等應用領域。
與C的關系
C語言是C++的基礎,C++和C語言在很多方面是兼容的。
C語言是一個結構化語言,它的重點在於算法與數據結構。C程序的設計首要考慮的是如何通過一個過程,對輸入(或環境 條件)進行運算處理得到輸出(或實現過程(事物)控制)。C++,首要考慮的是如何構造一個對象模型,讓這個模型能夠契合與之對應的問題域,這樣就可以通 過獲取對象的狀態信息得到輸出或實現過程(事物)控制。所以C語言和C++的最大區別在於它們解決問題的思想方法不一樣。
C++對C的“增強”,表現在六個方面:
(1) 類型檢查更為嚴格。
(2) 增加了面向對象的機制。
(3) 增加了泛型編程的機制(Template)。
(4) 增加了異常處理。
(5) 增加了運算符重載。
(6) 增加了標准模板庫(STL)。
與C不兼容之處
C++一般被認為是C的超集合(Superset),但這並不嚴謹。大部分的C代碼可以很輕易的在C++中正確編譯,但仍有少數差異,導致某些有效的C代碼在C++中失效,或者在C++中有不同的行為。
最常見的差異之一是,C允許從void*隱式轉換到其它的指針類型,但C++不允許。下列是有效的C代碼:
|
1
2
3
4
5
|
//從void*
類型隱式轉換為
int
*
類型
int
*i=
malloc
(
sizeof
(
int
)*5);
|
但要使其在C和C++兩者皆能運作,就需要使用顯式轉換:
|
1
|
int
*i=(
int
*)
malloc
(
sizeof
(
int
)*5);
|
另一個常見的可移植問題是,C++定義了新關鍵字,例如如new,class,它們在C程序中可以作為識別字(例:變量名)的。
在C標准(C99)中去除了一些不兼容之處,也支持了一些C++的特性,如//注解,以及在代碼中混合聲明。不過C99也納入幾個和C++沖突的新特性(如:可變長度數組、原生復數類型和復合逐字常數)。
若要混用C和C++的代碼,則所有在C++中調用的C代碼,必須放在 extern "C" { /* C代碼 */ } 內。
語言特點
優點:
· C++設計成靜態類型、和C同樣高效且可移植的多用途程序設計語言。
· C++設計直接的和廣泛的支持多種程序設計風格(程序化程序設計、資料抽象化、面向對象程序設計、泛型程序設計)。
· C++設計無需復雜的程序設計環境。
C++語言靈活,運算符的數據結構豐富、具有結構化控制語句、程序執行效率高,而且同時具有高級語言與匯編語言的優點,與其它語言相比 ,可以直接訪問物理地址,與匯編語言相比又具有良好的可讀性和可移植性。
總得來說,C++語言的主要特點表現在兩個方面,一是盡量兼容C,二是支持面向對象的方法。它操持了C的簡潔、高效的接近匯編語言等特點,對C的類型系統進行了改革的擴充,因此C++比C更安全,C++的編譯系統能檢查出更多的類型錯誤。另外,由於C語言的廣泛使用,因而極大的促進了C++的普及和推廣。
C++語言最有意義的方面是支持面向對象的特征。雖然與C的兼容使得C++具有雙重特點,但他在概念上完全與C不同,更具面向對象的特征。
出於保證語言的簡潔和運行高效等方面的考慮,C++的很多特性都是以庫(如STL)或其他的形式提供的,而沒有直接添加到語言本身里。關於此類話題,Bjarne Stroustrup的《C++語言的設計和演化》(1994)里做了詳盡的陳述。
C++引入了面向對象的概念,使得開發人機交互類型的應用程序更為簡單、快捷。很多優秀的程序框架包括Boost、Qt、MFC、OWL、wxWidgets、WTL就是使用的C++。
缺點
C++由於語言本身復雜。C++的編譯系統受到C++的復雜性的影響,非常難於編寫,即使能夠使用的編譯器如果存在問題,可能難於被發現。
由於本身的復雜性,復雜的C++程序的正確性相當難於保證。
優點:
· C++設計成靜態類型、和C同樣高效且可移植的多用途程序設計語言。
· C++設計直接的和廣泛的支持多種程序設計風格(程序化程序設計、資料抽象化、面向對象程序設計、泛型程序設計)。
· C++設計無需復雜的程序設計環境。
C++語言靈活,運算符的數據結構豐富、具有結構化控制語句、程序執行效率高,而且同時具有高級語言與匯編語言的優點,與其它語言相比 ,可以直接訪問物理地址,與匯編語言相比又具有良好的可讀性和可移植性。
總得來說,C++語言的主要特點表現在兩個方面,一是盡量兼容C,二是支持面向對象的方法。它操持了C的簡潔、高效的接近匯編語言等特點,對C的類型系統進行了改革的擴充,因此C++比C更安全,C++的編譯系統能檢查出更多的類型錯誤。另外,由於C語言的廣泛使用,因而極大的促進了C++的普及和推廣。
C++語言最有意義的方面是支持面向對象的特征。雖然與C的兼容使得C++具有雙重特點,但他在概念上完全與C不同,更具面向對象的特征。
出於保證語言的簡潔和運行高效等方面的考慮,C++的很多特性都是以庫(如STL)或其他的形式提供的,而沒有直接添加到語言本身里。關於此類話題,Bjarne Stroustrup的《C++語言的設計和演化》(1994)里做了詳盡的陳述。
C++引入了面向對象的概念,使得開發人機交互類型的應用程序更為簡單、快捷。很多優秀的程序框架包括Boost、Qt、MFC、OWL、wxWidgets、WTL就是使用的C++。
缺點
C++由於語言本身復雜。C++的編譯系統受到C++的復雜性的影響,非常難於編寫,即使能夠使用的編譯器如果存在問題,可能難於被發現。
由於本身的復雜性,復雜的C++程序的正確性相當難於保證。
數據類型
數據定義
數據是程序處理的對象,數據可以依其本身的特點進行分類。我們知道在數學中有整數、實數的概念,在日常生活中需要用字符串來表示人的姓名和地址,有些問題的 回答只能是“是”或“否”(即邏輯“真”或“假”)。不同類型的數據有不同的處理方法,例如:整數和實數可以參加算術運算,但實數的表示又不同於整數,要 保留一定的小數位;字符串可以拼接;邏輯數據可以參加“與”、“或”、“非”等邏輯運算。
我們編寫計算機程序,目的就是為了解決客觀世界中的現實問題。所以,高級語言中也為我們提供了豐富的數據類型和運算。C++中的數據類型分為基本類型和自定義類型。基本類型是C++編譯系統內置的。
基本類型
C++的基本數據類型如下表所示(下表中列出的各類型的長度和取值范圍,是指以面向80x86處理器的 Viusal C++ 2012 和 gcc 4.8.1 的長度,其它的編譯器並不一定是這個長度)。
| 類型名 | 長度(字節) | 取值范圍 |
| bool | 1 | false,true |
|
char
|
1 | -128~127 |
| signed char | 1 | -128~127 |
| unsigned char | 1 | 0~255 |
| short (signed short) | 2 | -32768~32767 |
| unsigned short | 2 | 0~65535 |
| int (signed int) | 4 | -2147483648~2147483647 |
| unsigned int | 4 | 0~4294967295 |
| long (signed long) | 4 | -2147483648~2147483647 |
| unsigned long | 4 | 0~4294967295 |
| long long (signed long long) | 8 | -9223372036854775807~9223372036854775807 |
| unsigned long long | 8 | 0~18446744073709551615 |
| float | 4 |
|
| double | 8 |
|
| long double | 8 |
|
類型轉換
C++豐富的數據類型允許根據需要選擇不同的類型,這也使得計算機的操作更復雜。
自動類型轉換(隱式類型轉換)
在下列四種情況中計算機自動進行類型轉換:
-
在混合類型的算術表達式中
int ival = 3;
double dval = 3.1415
ival + dval; //ival 被提升為double 類型:3.0 -
用另外一種類型的表達式賦值
int *pi = NULL; // NULL(0)被轉換成了int* 類型的空指針值 -
用一個表達式傳遞給一個函數調用
extern double sqrt(double);
sqrt(2); //2被提升為double類型: 2.0
強制類型轉換(顯示類型轉換)
C++顯式轉換包含四種轉換:
-
用法:static_cast < type-id > ( expression )說明:該運算符把expression轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。
-
用法:dynamic_cast < type-id > (expression)說明:該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void*;
-
用法:const_cast<type_id> (expression)說明:該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的類型是一樣的。
-
用法:reinterpret_cast<type-id> (expression)說明:type-id 必須是一個指針、引用、算術類型、函數指針或者成員指針。它可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還可以得到原先的指針值)。
編程技巧
new和delete
運算符new和delete提供了存儲的動態內存分配和釋放功能,它的作用相當於C語言的函數malloc()和free(),但性能更為優越。使用new較之使用malloc()有以下的幾個優點:
(1)new自動計算要分配類型的大小,不使用sizeof運算符,比較省事,可以避免錯誤。
(3)可以用new對分配的對象進行
初始化。
[9]
inline
對於頻繁使用的函數,C語言建議使用宏調用代替
函數調用以加快代碼執行,減少調用開銷。但是宏調用有許多的弊端,可能引起不期望的副作用。例如宏:#define abs(a)(a)<0?(-a):(a)),當使用abs(i++)時,這個宏就會出錯。
函數重載
在C語言中,兩個函數的名稱不能相同,否則會導致編譯錯誤。而在C++中,函數名相同而參數數據類型不同或參數個數不同或二者皆不同的兩個函數被解釋為重載。
使用
函數重載可以幫助程序員處理更多的復雜問題,避免了使用諸如intabs()、fabs()、dabs()等繁雜的函數名稱;同時在大型程序中,使函數名易於管理和使用,而不必絞盡腦汁地去處理函數名。同時必須注意,參數數據類型相同,但是函數返回類型不同的兩個函數不能重載。
[9]
參數傳遞
在 C語言中,如果一個函數需要修改用作參數的變量值的時候 ,參數應該聲明為指針類型;當參數的大小超過一個機器字長時,通過傳值方式來傳遞參數的效率較低,也需要用指針。由於C語言的指針可以進行p++,-- p,p+=1等算術運算,所以編譯器無法在編譯的時候確定指針引用的變量。對於復雜的程序,使用
指針容易出錯,程序也難以讀懂。在C++中,對於上述情況 可以使用引用來代替指針,使程序更加清晰易懂。引用就是對變量取的一個別名,對引用進行操作,這就相當於對原有變量進行操作。
[9]
缺省參數
在C++中函數可以使用
缺省參數。
通常的情況下,一個函數應該具有盡可能大的靈活性。使用缺省參數為程序員處理更大的復雜性和靈活性問題提供了有效的方法,所以在C++的代碼中都大量地使用了缺省參數。
需要說明的是,所有的缺省參數必須出現在不缺省參數的右邊。亦即,一旦開始定義缺省參數,就不可再說明非缺省的參數。否則當你省略其中一個參數的時候,編譯器無法知道你是自定義了這個參數還是利用了缺省參數而定義了非缺省的參數。
[9]
使用STL
STL(Standard Template Library,
標准模板庫),STL的代碼從廣義上講分為三類:algorithm(算法)、container(容器)和iterator(
迭代器),並包括一些工具類如
auto_ptr。幾乎所有的代碼都采用了
模板類和模板函數的方式,這相比於傳統的由函數和類組成的庫來說提供了更好的代碼重用機會。
使用模板
模板的概念
模板是C++的一個特性,是函數和類可以作用於不同的類型上而不需要針對每一個具體類型重復相同的代碼。與模板相反,我們已經學過的
重載(Overloading),對重載函數而言,C++的檢查機制能通過函數參數的不同及所屬類的不同。正確的調用
重載函數。例如,為求兩個數的最大值,我們定義MAX()函數需要對不同的數據類型分別定義不同
重載(Overload)版本。如果使用模板就可以只寫一個通用的MAX模板,而不需要針對每個類型重復相同的邏輯。
指針與引用的區別
指針與引用看上去完全不同(指針用操作符“*”和“->”,引用使用操作符“&”),但是它們似乎有相同的功能。指針與引用都是讓你間接引用其他對象。你如何決定在什么時候使用指針,在什么時候使用引用呢?
首先,要認識到在任何情況下都不能使用指向空值的引用。一個引用必須總是指向某些對象。因此如果你使用一個變量並讓 它指向一個對象,但是該變量在某些時候也可能不指向任何對象,這時你應該把變量聲明為指針,因為這樣你可以賦空值給該變量。相反,如果變量肯定指向一個對 象,例如你的設計不允許變量為空,這時你就可以把變量聲明為引用。
類和對象
類是具有相同屬性和相同的方法的對象的集合,它是一種既包含數據又包含函數的抽象數據類型。
對象是類進行實體化后的產物,是一個實體。
在C++中也是先聲明一個類類型,然后用它去定義若干個同類型的對象。對象就是類類型的一個變量。可以說類是對象的模板,是用來定義對象的一種抽象類型。類是抽象的,不占用內存,而對象是具體的,占用存儲空間。
聲明類類型
類是用戶自己指定的類型。如果程序中要用到類類型,必須自己根據需要進行聲明,或者使用別人已設計好的類。C++標准本身並不提供現成的類的名稱、結構和內容。
在C++中聲明一個類的類型和聲明一個結構體類型是相似的。下面是聲明一個結構體類型的方法:
|
1
2
3
4
5
6
7
8
|
struct
Student
//聲明了一個名為Student的結構體
類型
{
int
num;
char
name[20];
char
sex;
};
Student stud1,stud2;
//定義了兩個結構體變量stud1和stud2,它只包括數據,沒有包括操作
|
聲明一個類:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class
Student
//以class開頭
{
int
num;
char
name[20];
char
sex;
//以上3行是數據成員
void
display()
//這是成員函數
{
cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;
};
//以上4行是函數中的操作語句
};
Student stud,stud1;
//定義了兩個對象stud和stud
|
事實上,也可以用struct關鍵字來聲明一個類。這樣的類中默認所有成員的權限都是public(除非你特別寫上權限),而用class聲明的類中默認所有成員的權限都是private.
可以看到聲明類的方法是由聲明結構體類型的方法發展而來的,類就是對象的類型。實際上,類是一種廣義的數據類型。類這種數據類型中的數據既包含數據,也包含操作數據的函數。
不能把類中的全部成員與外界隔離,一般是把數據隱蔽起來,而把成員函數作為對外界的
接口。可以將上面類的聲明改為
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
Student
//以class開頭
{
private
:
//聲明私有成員
intnum;
char
name[20];
char
sex;
public
:
//聲明公共成員
void
display()
{
cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;
}
};
Student stud1,stud2;
//定義了兩個對象stud1和stud2
|
如果在類的定義中既不指定private,也不指定public,則系統就默認為是私有的。歸納以上對類類型的聲明,可得到其一般形式如下:
|
1
2
3
4
5
6
7
8
9
|
class
類名
{
private
:
//私有的數據和成員函數;
public
:
//公用的數據和成員函數;
};
|
private 和public稱為成員訪問限定符(member access specifier)。除了private和public之外,還有一種成員訪問限定符protected(受保護的),用protected聲明的成員 稱為受保護的成員,它不能被類外訪問(這點與私有成員類似),但可以被派生類的成員函數訪問。
在聲明類類型時,聲明為private的成員和聲明為public的成員的次序任意,既可以先出現private部分,也可以先出現public部分。
在一個類體中,關鍵字private和public可以分別出現多次。每個部分的有效范圍到出現另一個訪問限定符或類體結束時(最后一個右花括號)為止。但是為了使程序清晰,應該養成這樣的習慣: 使每一種成員訪問限定符在類定義體中只出現一次。
C++ 程序多數先寫public部分,把private部分放在類體的后部。這樣可以使用戶將注意力集中在能被外界調用的成員上,使閱讀者的思路更清晰一些。
在C++程序中,經常可以看到類。為了用戶方便,常用的C++編譯系統往往向用戶提供
類庫(但不屬於C++語言的組成部分),內裝常用的基本的類,供用戶使用。不少用戶也把自己或本單位經常用到的類放在一個專門的類庫中,需要用時直接調用,這樣就減少了程序設計的工作量。
定義對象
上述程序段中,最后一行用已聲明的Student類來定義對象,這種方法是很容易理解的。經過定義后,stud1和stud2就成為具有Student類特征的對象。stud1和stud2這兩個對象都分別包括Student類中定義的數據和函數。
定義對象也可以有以下幾種方法:
1.先聲明類類型,然后再定義對象前面用的就是這種方法,如Student stud1,stud2;//Student是已經聲明的類類型在C++中,聲明了類類型后,定義對象有兩種形式。
(1)class 類名 對象名
如: class Student stud1,stud2;
把class和Student合起來作為一個類名,用來定義對象。
(2)類名 對象名
如: Student stud1,stud2;
直接用類名定義對象。
這兩種方法是等效的。第1種方法是從C語言繼承下來的,第2種方法是C++的特色,顯然第2種方法更為簡捷方便。
2.在聲明類類型的同時定義對象
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
Student{
//聲明
類
類型
public
:
//先聲明公用部分
void
display(){
cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;
}
private
:
//后聲明私有部分
int
num;
char
name[20];
char
sex;
}stud1,stud2;
//定義了兩個Student
類的對象
|
在定義Student類的同時,定義了兩個Student 類的對象。
3.不出現類名,直接定義對象
|
1
2
3
4
5
6
7
8
9
10
11
|
class
//無
類名
{
private
:
//聲明以下部分為私有的
//...
public
:
//聲明以下部分為公用的
//...
}stud1,stud2;
//定義了兩個無
類名的
類對象
|
直接定義對象,在C++中是合法的、允許的,但卻很少用,也不提倡用。在實際的程序開發中,一般都采用上面3種方法中的第1種方法。在小型程序中或所聲明的類只用於本程序時,也可以用第2種方法。在定義一個對象時,編譯系統會為這個對象分配存儲空間,以存放對象中的成員。
類和結構體
C++增加了class類型后,仍保留了結構體類型(struct ),而且把它的功能也擴展了。C++允許用struct來定義一個類型。如可以將前面用關鍵字class聲明的類類型改為用關鍵字struct:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
structStudent{
//用關鍵字struct來聲明一個
類
類型
private
:
//聲明以下部分為私有的
int
num;
//以下3行為數據成員
char
name[20];
char
sex;
public
:
//聲明以下部分為公用的
void
display(){
//成員函數
cout<<″num:″<<num<<endl;
cout<<″name:″<<name<<endl;
cout<<″sex:″<<sex<<endl;
}
};
Student stud1,stud2;
//定義了兩個Student
類的對象
|
為 了使結構體類型也具有封裝的特征,C++不是簡單地繼承C的結構體,而是使它也具有類的特點,以便於用於面向對象程序設計。用struct聲明的結構體類 型實際上也就是類。用struct聲明的類,如果對其成員不作private或public的聲明,系統將其默認為public。
如果想分別指定私有成員和公用成員,則應用private或public作顯式聲明。
而用class定義的類,如果不作private或public聲明,系統將其成員默認為private,在需要時 也可以自己用顯式聲明改變。如果希望成員是公用的,使用struct比較方便,如果希望部分成員是私有的,宜用class。建議盡量使用class來建立 類,寫出完全體現C++風格的程序。
關鍵字
關鍵字(keyword)是整個語言范圍內預先保留的標識符。每個C++關鍵字都有特殊的含義。經過預處理后,關鍵字從預處理記號 (preprocessing-token)中區出來,剩下的標識符作為記號(token),用於聲明對象、函數、類型、命名空間等。不能聲明與關鍵字同 名的標識符。
各個版本的ISO C++都規定以下划線接大寫字母起始的標識符保留給實現。編譯器可以用這些保留標識符作為擴展關鍵字,這不保證可移植性。以下討論ISO C++所保留的關鍵字。
ISO C++ 98 關鍵字共63個,此處嚴格按標准原文排版:
|
asm
|
do
|
if
|
return
|
typedef
|
|
auto
|
double
|
inline
|
short
|
typeid
|
|
bool
|
dynamic_cast
|
int
|
signed
|
typename
|
|
break
|
else
|
long
|
sizeof
|
union
|
|
case
|
enum
|
mutable
|
static
|
unsigned
|
|
catch
|
explicit
|
namespace
|
static_cast
|
using
|
|
char
|
export
|
new
|
struct
|
virtual
|
|
class
|
extern
|
operator
|
switch
|
void
|
|
const
|
false
|
private
|
template
|
volatile
|
|
const_cast
|
float
|
protected
|
this
|
wchar_t
|
|
continue
|
for
|
public
|
throw
|
while
|
|
default
|
friend
|
register
|
true
|
|
|
delete
|
goto
|
reinterpret_cast
|
try
|
代碼實現
一個程序從編寫到最后得到運行結果要經歷以下一些步驟:
1、用C++語言編寫程序
| Unix: | C, cc, cxx, c |
| GNU C++: | C, cc, cxx, cpp, c++ |
| Digital Mars: | cpp, cxx |
| Borland: | C++ cpp |
| Watcom: | cpp |
| Microsoft Visual C++: | cpp, cxx, cc |
| Metrowerks CodeWarrior: | cpp, cp, cc, cxx, c++ |
2、對源程序進行編譯
為了使計算機能執行高級語言源程序,必須先用一種稱為“
編譯器(complier)”的軟件(也稱編譯程序或編譯系統),把源程序翻譯成二進制形式的“目標程序(object program)。
編譯是以源程序文件為單位分別編譯的。目標程序一般以.obj或.o作為后綴(object 的縮寫)。編譯的作用是對源程序進行詞法檢查和語法檢查。編譯時對文件中的全部內容進行檢查,編譯結束后會顯示出所有的編譯出錯信息。一般編譯系統給出的 出錯信息分為兩種,一種是錯誤(error);一種是警告(warning) 。
3、將目標文件連接
在改正所有的錯誤並全部通過
編譯后,得到一個或多個目標文件。此時要用系統提供的“連接程序(linker)”將一個程序的所有目標程序和系統的庫文件以及系統提供的其他信息連接起來,最終形成一個可執行的二進制文件,它的后綴是.exe,是可以直接執行的。
4、運行程序
運行最終形成的可執行的二進制文件(.exe文件),得到運行結果。
如果運行結果不正確,應檢查程序或算法是否有問題。
命令行開發方式
3.make:GNU make 或者BSD的pmake等,功能與用法基本一樣
5.代碼閱讀:
cscope,ctags,lxr等
集成開發環境(IDE)
1.
Microsoft Visual Studio(Visual C++)
[11]
2.Borland C++ Builder
3.
Eclipse (Myln + CDT + MinGW32 + GCC)
4.
Dev-C++ (MinGW32 + GCC)
5.
Code::Blocks(可配合多款編譯器使用)
6.
CodeLite
7.
C-Free
8.
Qt Creator (可配合多款編譯器使用)
9.
KDevelop
實際上,當前流行的編譯器只有五種:Intel C++ 編譯器、微軟的cl.exe編譯器(捆綁於Visual Studio套裝中)、GNU的GCC編譯器、LLVM的Clang編譯器、Borland公司的bcc.exe編譯器(捆綁於Borland C++ Builder套裝中)。
多泛型設計
根據Effective C++第三版第一條款的描述,C++由以下四個“子語言”組成:
1、C子語言。C++支持C語言的幾乎全部功能,主要是c89的部分,在語法上與C語言僅有極微妙的差別(如括號表達式的左右值性,具體請參考C++標准文獻)。這部分功能對應於傳統的面向過程的編程泛型,並提供了面向函數編程泛型的基礎。
3、泛型編程語言。C++強大(但容易失控的)模板功能使它能在編譯期完成許多工作,從而大大提高運行期效率,並且大大提高了C++的表達能力。
STL(C++ 標准模板庫,Standard Template Library)是一個基於模板技術的庫。隨着STL的不斷發展,它已經逐漸成為C++程序設計中不可或缺的部分,其效率可能比一般的native代碼低 些,但是其安全性與規范性使它大受歡迎。模板使C++能夠支持泛型編程(generic programming)和生成式編程(generative programming)的泛型。
4、在C++11中引入的Lambda,使得程序員可以定義匿名函數,完善了C++對於面向函數的編程泛型的支持。
經典著作
入門書籍
《C++ Primer 中文版(第5版)》
《C++ Primer (Fifth Edition)》
《C++ Primer Plus 中文版(第六版)》
《C++ Primer Plus (Sixth Edition)》
進階書籍
《Thinking in C++》
《A Tour Of C++》
《C++編程思想》
《The C++ Programming Language (Fourth Edition)》
《C++程序設計語言(第四版)》(未出版)
《Essential C++》
《The C++ Standard Library: A Tutorial and Reference》
《C++標准程序庫:自修教程與參考手冊》
《Effective STL》
《Generic Programming and the STL: Using and Extending the C++ Standard Template Library》
《泛型編程與STL》
《C++語言的設計和演化》
《C++標准程序庫:自修教程與參考手冊》
《STL源碼剖析》
高階書籍
《Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference》
《標准C++輸入輸出流與本地化》
《C++ Network Programming》
《C++網絡編程》
《Ruminations on C++: A Decade of Programming Insight and Experience》
《C++沉思錄》
《Inside The C++ Object Model》
《深度探索C++對象模型》
《Design Patterns:Elements of Reusable Object-Oriented software》
《設計模式:可復用面向對象軟件的基礎》
《Large-Scale C++ Software Design》(《大規模C++程序設計》);
《STL 源碼剖析》;
《The C++ Standard : Incorporating Technical Corrigendum No. 1》;
《Preprocessor C++》
《C++語言基礎》
《Essential C++》
《(More)Effective C++》
《C++ Templates》
《高質量C++編程指南——上海貝爾標准編程文檔 》
常見錯誤
|
英文
|
參考譯文
|
|---|---|
|
Ambiguous operators need parentheses
|
模棱兩可的操作符需要括號
|
|
Ambiguous symbol ''xxx''
|
不明確的符號
|
|
Argument list syntax error
|
參數表語法錯誤
|
|
Array bounds missing
|
數組界限符丟失
|
|
Array size toolarge
|
數組尺寸太大
|
|
Bad character in paramenters
|
參數中有不適當的字符
|
|
Bad file name format in include directive
|
包含命令中文件名格式不正確
|
|
Bad ifdef directive synatax
|
編譯預處理ifdef有語法錯
|
|
Bad undef directive syntax
|
編譯預處理undef有語法錯
|
|
Bit field too large
|
位字段太長
|
|
Call of non-function
|
調用未定義的函數
|
|
Call to function with no prototype
|
調用函數時沒有函數的說明
|
|
Cannot modify a const object
|
不允許修改常量對象
|
|
Case outside of switch
|
漏掉了case 語句
|
|
Case syntax error
|
Case 語法錯誤
|
|
Code has no effect
|
代碼不可能被執行到
|
|
Compound statement missing{
|
分程序漏掉"{"
|
|
Conflicting type modifiers
|
互相沖突的類型說明符設置
|
|
Constant expression required
|
需要常量表達式
|
|
Constant out of range in comparison
|
在比較中常量超出范圍
|
|
Conversion may lose significant digits
|
轉換時會丟失數值的精度
|
|
Conversion of near pointer not allowed
|
不允許轉換近指針
|
|
Could not find file ''xxx''
|
找不到XXX文件
|
|
Declaration missing ;
|
聲明中缺少";"
|
|
Declaration syntax error
|
聲明中出現語法錯誤
|
|
Default outside of switch
|
Default 出現在switch語句之外
|
|
Define directive needs an identifier
|
定義編譯預處理需要標識符
|
|
Division by zero
|
用零作除數
|
|
Do statement must have while
|
Do-while語句中缺少while部分
|
|
Enum syntax error
|
枚舉類型語法錯誤
|
|
Enumeration constant syntax error
|
枚舉常數語法錯誤
|
|
Error directive :xxx
|
錯誤的編譯預處理命令
|
|
Error writing output file
|
寫輸出文件錯誤
|
|
Expression syntax error
|
表達式語法錯誤
|
|
Extra parameter in call
|
調用時出現多余錯誤
|
|
File name too long
|
文件名太長
|
|
Function call missing
|
函數調用缺少右括號
|
|
Fuction definition out of place
|
函數定義位置錯誤
|
|
Fuction should return a value
|
函數必需返回一個值
|
|
Goto statement missing label
|
Goto語句沒有標號
|
|
Hexadecimal or octal constant too large
|
16進制或8進制常數太大
|
|
Illegal character ''x''
|
非法字符x
|
|
Illegal initialization
|
非法的初始化
|
|
Illegal octal digit
|
非法的8進制數字
|
|
Illegal pointer subtraction
|
非法的指針相減
|
|
Illegal structure operation
|
非法的結構體操作
|
|
Illegal use of floating point
|
非法的浮點運算
|
|
Illegal use of pointer
|
指針使用非法
|
|
Improper use of a typedefsymbol
|
類型定義符號使用不恰當
|
|
In-line assembly not allowed
|
不允許使用行間匯編
|
|
Incompatible storage class
|
存儲類別不相容
|
|
Incompatible type conversion
|
不相容的類型轉換
|
|
Incorrect number format
|
錯誤的數據格式
|
|
Incorrect use of default
|
Default使用不當
|
|
Invalid indirection
|
無效的間接運算
|
|
Invalid pointer addition
|
指針相加無效
|
|
Irreducible expression tree
|
無法執行的表達式運算
|
|
Lvalue required
|
需要邏輯值0或非0值
|
|
Macro argument syntax error
|
宏參數語法錯誤
|
|
Macro expansion too long
|
宏的擴展以后太長
|
|
Mismatched number of parameters in definition
|
定義中參數個數不匹配
|
|
Misplaced break
|
此處不應出現break語句
|
|
Misplaced continue
|
此處不應出現continue語句
|
|
Misplaced decimal point
|
此處不應出現小數點
|
|
Misplaced elif directive
|
不應編譯預處理elif
|
|
Misplaced else
|
此處不應出現else
|
|
Misplaced else directive
|
此處不應出現編譯預處理else
|
|
Misplaced endif directive
|
此處不應出現編譯預處理endif
|
|
Must be addressable
|
必須是可以編址的
|
|
Must take address of memory location
|
必須存儲定位的地址
|
|
No declaration for function ''xxx''
|
沒有函數xxx的說明
|
|
No stack
|
缺少堆棧
|
|
No type information/沒有類型信息
|
缺少堆棧
|
|
Non-portable pointer assignment
|
不可移動的指針(地址常數)賦值
|
|
Non-portable pointer comparison
|
不可移動的指針(地址常數)比較
|
|
Non-portable pointer conversion
|
不可移動的指針(地址常數)轉換
|
|
Not a valid expression format type
|
不合法的表達式格式
|
|
Not an allowed type
|
不允許使用的類型
|
|
Numeric constant too large
|
數值
常太大
|
|
Out of memory
|
內存不夠用
|
|
Parameter ''xxx'' is never used
|
能數xxx沒有用到
|
|
Pointer required on left side of ->
|
符號->的左邊必須是指針
|
|
Possible use of ''xxx'' before definition
|
在定義之前就使用了xxx(警告)
|
|
Possibly incorrect assignment
|
賦值可能不正確
|
|
Redeclaration of ''xxx''
|
重復定義了xxx
|
|
Redefinition of ''xxx'' is not identical
|
xxx的兩次定義不一致
|
|
Register allocation failure
|
寄存器定址失敗
|
|
Repeat count needs an lvalue
|
重復計數需要邏輯值
|
|
Size of structure or array not known
|
結構體或數給大小不確定
|
|
Statement missing ;
|
語句后缺少";"
|
|
Structure or union syntax error
|
結構體或聯合體語法錯誤
|
|
Structure size too large
|
結構體尺寸太大
|
|
Sub scripting missing ]
|
下標缺少右方括號
|
|
Superfluous & with function or array
|
函數或數組中有多余的"&"
|
|
Suspicious pointer conversion
|
可疑的指針轉換
|
|
Symbol limit exceeded
|
符號超限
|
|
Too few parameters in call
|
函數調用時的實參少於函數的參數不
|
|
Too many default cases
|
Default太多(switch語句中一個)
|
|
Too many error or warning messages
|
|
英文
|
參考譯文
|
|---|---|
|
Too many type in declaration
|
說明中類型太多
|
|
Too much auto memory in function
|
函數用到的局部存儲太多
|
|
Too much global data defined in file
|
文件中全局數據太多
|
|
Two consecutive dots
|
兩個連續的句點
|
|
Type mismatch in parameter xxx
|
參數xxx類型不匹配
|
|
Type mismatch in redeclaration of ''xxx''
|
xxx重定義的類型不匹配
|
|
Unable to create output file ''xxx''
|
無法建立輸出文件xxx
|
|
Unable to open include file ''xxx''
|
無法打開被包含的文件xxx
|
|
Unable to open input file ''xxx''
|
無法打開輸入文件xxx
|
|
Undefined label ''xxx''
|
沒有定義的標號xxx
|
|
Undefined structure ''xxx''
|
沒有定義的結構xxx
|
|
Undefined symbol ''xxx''
|
沒有定義的符號xxx
|
|
Unexpected end of file in comment started on line xxx
|
從xxx行開始的注解尚未結束文件不能結束
|
|
Unexpected end of file in conditional started on line xxx
|
從xxx 開始的條件語句 尚未結束文件不能結束
|
|
Unknown assemble instruction
|
未知的匯編結構
|
|
Unknown option
|
未知的操作
|
|
Unknown preprocessor directive: ''xxx''
|
不認識的預處理命令xxx
|
|
Unreachable code
|
無路可達的代碼
|
|
Unterminated string or character constant
|
字符串缺少引號
|
|
User break
|
用戶強行中斷了程序
|
|
Void functions may not return a value
|
Void類型的函數不應有返回值
|
|
Wrong number of arguments
|
調用函數的參數數目錯
|
|
''xxx'' not an argument
|
xxx不是參數
|
|
''xxx'' not part of structure
|
xxx不是結構體的一部分
|
|
xxx statement missing (
|
xxx語句缺少左括號
|
|
xxx statement missing )
|
xxx語句缺少右括號
|
|
xxx statement missing ;
|
xxx缺少分號
|
|
xxx'' declared but never used
|
說明了xxx但沒有使用
|
|
xxx'' is assigned a value which is never used
|
給xxx賦了值但未用過
|
|
Zero length structure
|
C++ 標准
C++ 98 標准
絕大多數編譯器都支持C++98標准。不過當時錯誤地引入了export關鍵字。由於技術上的實現難度,除了 Comeau C++編譯器export關鍵字以外,沒有任何編譯器支持export關鍵字。並且這個標准對現代的一些編譯理念有相當的差距,有很多在高級語言都應當有 的功能,它都沒有。這也正是后來需要制定C++11標准的原因所在。
C++ 03 標准
C++標准第二版,2003年發布。正式名稱為
ISO/IEC 14882:2003
[18]
。這個標准僅僅是C++98修訂版,與C++98幾乎一樣,沒做什么修改。僅僅是對C++98做了一些“勘誤”,就連主流編譯器(受C99標准影響)都已支持的long long都沒有被加入C++03標准。
C++ 11 標准
由C++標准委員會於2011年8月12日公布,並於2011年9月出版。2012年2月28日的國際標准草案 (N3376)是最接近於現行標准的草案(編輯上的修正)。C++11包含了核心語言的新機能,並且拓展C++標准程序庫,並且加入了大部分的C++ Technical Report 1程序庫(數學上的特殊函數除外)。此次標准為C++98發布后13年來第一次重大修正。
注意:
C++11標准(ISO/IEC 14882:2011)與
C11標准(ISO/IEC 9899:2011)是兩個完全不同的標准,后者是C語言的標准。
C++ 14 標准
2014年8月18日,ISO組織在其網站上發布文章稱:
C++ 作者 Bjarne Stroustrup 稱,主要的編譯器開發商已經實現了 C++ 14 規格。
C++ 14 是 C++ 11 的增量更新,主要是支持普通函數的返回類型推演,泛型 lambda,擴展的 lambda 捕獲,對 constexpr 函數限制的修訂,constexpr變量模板化等等。
