目錄
第一部分 語法篇
第2章 從C到C++
建議19:在C++中使用C
C++雖然兼容絕大部分C的語法,但是還是有些不兼容。比如,C允許從void類型指針隱式轉(zhuǎn)換成其他類型的指針,但是C++禁止此行為。
// 從void* 隱式轉(zhuǎn)換成double*
double* p = malloc(nCount * sizeof(double))
在C++中調(diào)用C代碼的幾種方式:
// 1.在原函數(shù)聲明前添加
extern "C" int Function(void);
// 2.在調(diào)用函數(shù)的C++代碼中重新聲明一下C函數(shù)
extern "C" int Function(void);
// 3.在包含C頭文件時添加
extern "C" {
#include "CDemo.h"
}
建議20:小心memcpy、memset、memcmp等內(nèi)存操作函數(shù)
C語言的數(shù)據(jù)類型叫做POD對象(Plain Old Data)。POD對象的二進(jìn)制內(nèi)容是可以隨意復(fù)制的,在內(nèi)存中是連續(xù)的,能通過對象的基地址和數(shù)據(jù)成員的偏移量獲取數(shù)據(jù)成員的地址。所以可以使用這些內(nèi)存操作函數(shù)操作POD對象。
但是,C++中的對象可能不是POD,因?yàn)槎鄳B(tài)會用到虛函數(shù)表,對象的數(shù)據(jù)體中不僅有數(shù)據(jù)成員,還有虛函數(shù)表。對象的數(shù)據(jù)成員在內(nèi)存中是不連續(xù)的。
建議21:用new/delete代替malloc/free
- new/delete,運(yùn)算符。會調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)。
- malloc/free,庫函數(shù)。僅實(shí)現(xiàn)內(nèi)存的分配和釋放。
- 通過new創(chuàng)建的東西具有類型,而malloc函數(shù)返回的是void*,使用時需要進(jìn)行強(qiáng)制轉(zhuǎn)換
- new失敗時會調(diào)用new_handler處理函數(shù),而malloc失敗則返回NULL
- delete可以自動調(diào)用對象的析構(gòu)函數(shù),而malloc不會
建議22:靈活使用不同風(fēng)格的注釋
- 版權(quán)聲明用C風(fēng)格的
/**/ - 注釋嵌套時,內(nèi)嵌的注釋用
// - 宏尾端的注釋用
/**/
一種特殊情形:默認(rèn)參數(shù)函數(shù)的定義。
在實(shí)現(xiàn)文件中添加C風(fēng)格的注釋,使程序更加清晰易懂。
// 聲明文件
class A
{
public:
void Function(int para1, int para2 = 0);
};
// 實(shí)現(xiàn)文件
void A::Function(int para1, int para2 /* = 0 */)
{
}
建議23:盡量使用C++標(biāo)準(zhǔn)的iostream
幾類頭文件
- "stdio.h",標(biāo)準(zhǔn)化以前C++中的C標(biāo)準(zhǔn)庫
- "cstdio.h",標(biāo)準(zhǔn)化后經(jīng)過改造的C標(biāo)準(zhǔn)庫,用std包裝,例如std::printf()
- "iostream.h",沒有用std包裝的C++"準(zhǔn)"標(biāo)準(zhǔn)庫
- "iostream",用std包裝的C++標(biāo)準(zhǔn)庫,首選
建議24:盡量使用C++風(fēng)格的強(qiáng)制轉(zhuǎn)型
C++風(fēng)格的強(qiáng)制變換更安全,參考建議11
建議25:盡量使用const、enum、inline替換#define
從源代碼到二進(jìn)制文件的過程:預(yù)處理->編譯->鏈接。宏替換在預(yù)處理階段。
盡量將工作交給編譯器,而不是預(yù)處理器。
- 用內(nèi)聯(lián)函數(shù)替換宏定義函數(shù),既可以得到宏的高效,又能保證類型安全
template <typename T>
inline T Add(const T&a, const T& b)
{
return (a+b);
}
- 常量指針與指向常量的指針:如果const出現(xiàn)在
*左邊,則數(shù)據(jù)為常量;如果在*右邊,則指針為常量。
const int * p = 123; // 指向常量的指針
int * const p = 123; // 常指針
const int * const p = 123; // 指向常量的長指針
建議26:用引用代替指針
引用只是對應(yīng)實(shí)體的別名,引用必須初始化。
引用不占任何存儲空間,因此不存在引用的引用、指向引用的指針(實(shí)質(zhì)上是指向被引用實(shí)體的指針)、引用的數(shù)組。