一、new和malloc的區(qū)別
1、new和delete配對(duì),釋放數(shù)組需要用delete[]。new和delete實(shí)際上調(diào)用了malloc和free,另外調(diào)用了類(lèi)的構(gòu)造函數(shù)和析構(gòu)函數(shù)。2、malloc和free配對(duì),malloc返回的是void指針,需要強(qiáng)轉(zhuǎn)。
3、new申請(qǐng)的內(nèi)存保存在堆中,malloc申請(qǐng)的內(nèi)存保存在自由存儲(chǔ)區(qū)。
二、C++運(yùn)算符
1、取模操作符:%2、邏輯否、與、或:!, &&, ||3、三元操作符:c = (a>b) ? a : b;4、按位與、或、非& AND 邏輯與 Logic AND| OR 邏輯或Logic OR~ NOT 對(duì)1取補(bǔ)(位反轉(zhuǎn))Complement to one (bit inversion)5、按位移:<< SHL 左移Shift Left>> SHR 右移Shift Right
三、&: 取地址運(yùn)算符、定義變量引用
&操作符用于取地址時(shí)的用法是:int* x=&y;。
然而,另外一種用法是定義變量別名,這種用法不能和取地址簡(jiǎn)單等同。用于傳遞函數(shù)輸入?yún)?shù)時(shí)很好理解,但定義變量時(shí)容易引起理解錯(cuò)誤,特別是和指針的區(qū)別:
從內(nèi)存的角度看,指針和引用是完全不同的。指針,內(nèi)存要為它分配一個(gè)存儲(chǔ)空間。引用,內(nèi)存不分配空間的,引用只是一個(gè)別名。我認(rèn)為就是在符號(hào)表里增加一個(gè)標(biāo)志而已,對(duì)于語(yǔ)句int &y=x; (&x=&y)為true。實(shí)際上“引用”可以做的任何事情“指針”也都能夠做,為什么還要“引用”這東西?答案是“用適當(dāng)?shù)墓ぞ咦銮∪缙浞值墓ぷ鳌薄.?dāng)重載某個(gè)操作符時(shí),你應(yīng)該使用引用。最普通的例子是操作符[]。這個(gè)操作符典型的用法是返回一個(gè)目標(biāo)對(duì)象,其能被賦值。如果操作符[]返回一個(gè)指針,那么后一個(gè)語(yǔ)句就得這樣寫(xiě):*v[5] = 10; 但是這樣會(huì)使得v看上去象是一個(gè)向量指針。因此你會(huì)選擇讓操作符返回一個(gè)引用。
引用的一些規(guī)則如下: (1)引用被創(chuàng)建的同時(shí)必須被初始化(指針則可以在任何時(shí)候被初始化),否則會(huì)報(bào)編譯錯(cuò)誤。 (2)一旦引用被初始化,就不能改變引用的關(guān)系(指針則可以隨時(shí)改變所指的對(duì)象)。 以下示例程序中,k被初始化為i的引用。語(yǔ)句k = j并不能將k 修改成為j 的引用,只是把k的值改變成為6。由于k是i的引用,所以i 的值也變成了6。 int i = 5; int j = 6; int &k = i; k = j; // k 和i 的值都變成了6;(3)不能有NULL 引用,引用必須與合法的存儲(chǔ)單元關(guān)聯(lián)(指針則可以是NULL)。 以下的寫(xiě)法將地址指向一個(gè)位置的內(nèi)存,是錯(cuò)誤的。結(jié)果將是不確定的(編譯器能產(chǎn)生一些輸出,導(dǎo)致任何事情都有可能發(fā)生)char pc = 0; // 設(shè)置指針為空值 char& rc = pc; // 讓引用指向空值(4)“sizeof 引用”得到的是所指向的變量(對(duì)象)的大小,但是當(dāng)引用作為成員時(shí),其占用空間與指針相同(沒(méi)找到標(biāo)準(zhǔn)的規(guī)定)。
(5)引用只能指向一個(gè)實(shí)際的變量,不能指向指針或引用(int) * p1; // p1是指針的指針(int) & p2; // p2是指向整型指針的引用引用不能指向指針或引用!(int&) * p3; // ERROR: 不能有指向引用的指針,因?yàn)橐弥皇且粋€(gè)別名(int&) & p4; // ERROR: 不能有指向引用的引用,因?yàn)橐弥皇且粋€(gè)別名(6)指針和引用在內(nèi)部的實(shí)現(xiàn)其實(shí)是沒(méi)多大的區(qū)別的。但使用時(shí)有些地方是要注意的。因?yàn)橐镁哂袑?duì)象行為,這一點(diǎn)很重要。引用復(fù)制時(shí)會(huì)調(diào)用對(duì)象的復(fù)制函數(shù),在涉及多態(tài)時(shí),這地方很容易出錯(cuò)。class A{...};class B:public A{...};void f(A&a1,A&a2){a1=a2;//此處調(diào)用的只有基類(lèi)A的復(fù)制函數(shù),而B(niǎo)部分不會(huì)被進(jìn)行復(fù)制,之將導(dǎo)致數(shù)據(jù)的不一致(即B部分的數(shù)據(jù)沒(méi)有被復(fù)制);a1.fun();}
四、關(guān)于const
一般的const變量:
下面兩個(gè)聲明都指向一個(gè)const int類(lèi)型的指針,指針?biāo)赶虻膬?nèi)存不能被修改,但指針可以指向另一個(gè)內(nèi)存:const int *p; int const *q; int類(lèi)型的const指針應(yīng)該這樣聲明。指針?biāo)赶虻膬?nèi)存可以被修改,但指針不能指向另一個(gè)內(nèi)存int * const r= &n;
聲明一個(gè)指向const int類(lèi)型的const指針:const int * const p=&n;
const在函數(shù)聲明中的含義:
const int& SetPoint(const int& param) const第一個(gè)const:函數(shù)的返回值限定為const,即返回值不能被修改。const int a=SetPoint(...) a在此之后便不能被修改。第二個(gè)const:指函數(shù)的形參為const類(lèi)型,函數(shù)體內(nèi)不能被修改.第三個(gè)const:表明這個(gè)函數(shù)不會(huì)對(duì)這個(gè)類(lèi)對(duì)象的數(shù)據(jù)成員(準(zhǔn)確地說(shuō)是非靜態(tài)數(shù)據(jù)成員)作任何改變。
類(lèi)的const和static成員變量的初始化:
對(duì)于static成員變量,如果同時(shí)是const的,可以在類(lèi)定義中初始化,否則只能在類(lèi)定義外部初始化。非static的const成員變量只能在構(gòu)造函數(shù)的初始化列表中初始化。(ClassName():m_1(1){};)
五、一些數(shù)據(jù)類(lèi)型和變量賦值語(yǔ)法
1、union 中的所有被聲明的元素占據(jù)同一段內(nèi)存空間,其大小取聲明中最長(zhǎng)的元素的大小。union 的用途之一是將一種較長(zhǎng)的基本類(lèi)型與由其它比較小的數(shù)據(jù)類(lèi)型組成的結(jié)構(gòu)(structure)或數(shù)組(array)聯(lián)合使用。2、long double和float變量的賦值方法:3.14159L // long double6.02e23f // float3、容易引起理解錯(cuò)誤的定義語(yǔ)句:int* p,q; 第一眼看去,好像是p和q都是int*類(lèi)型的,但事實(shí)上,只有p是一個(gè)指針,而q是一個(gè)最簡(jiǎn)單的int型變量。同時(shí)定義兩個(gè)指針的語(yǔ)法是:int *p1, p2;
4、定義一個(gè)指向int[4]數(shù)組的指針變量int (p)[4]=RollNum;這里,p被聲明為一個(gè)指向一個(gè)4元素(int類(lèi)型)數(shù)組的指針。5、未指定size情況下,char數(shù)組的大小由初始化字符串決定:我們可以用下面兩種方法的任何一種來(lái)初始化字符串mystring:char mystring [ ] = { 'H', 'e', 'l', 'l', 'o', '/0' };char mystring [ ] = "Hello";在兩種情況下字符串或數(shù)組mystring都被定義為6個(gè)字符長(zhǎng)(元素類(lèi)型為字符char):組成Hello的5個(gè)字符加上最后的空字符('/0')。在第二種用雙引號(hào)的情況下,空字符('/0')是被自動(dòng)加上的。兩種情況下sizeof應(yīng)該都是6,strlen都是5。
六、常用的幾個(gè)標(biāo)準(zhǔn)C++函數(shù)
1、cout和cin的用法:cout << "xxx" << endl;cin >> "yyy";
2、常用的字符串函數(shù):strcat //字符串拼接strcpystrncpystrcmp //字符串比較,相同返回0
七、switch-case的寫(xiě)法
switch (expression) {case constant1:block of instructions 1break;case constant2:block of instructions 2break;...default:default block of instructions}
八、函數(shù)的幾個(gè)屬性和用法
1、指定函數(shù)的默認(rèn)參數(shù)值int divide (int a, int b=2) {
2、什么是函數(shù)重載(Overloaded functions)兩個(gè)不同的函數(shù)可以用同樣的名字,只要它們的參量(arguments)的原型(prototype)不同,也就是說(shuō)你可以把同一個(gè)名字給多個(gè)函數(shù),如果它們用不同數(shù)量的參數(shù),或不同類(lèi)型的參數(shù)。
3、內(nèi)聯(lián)函數(shù)
inline 指令可以被放在函數(shù)聲明之前,要求該函數(shù)必須在被調(diào)用的地方以代碼形式被編譯。這相當(dāng)于一個(gè)宏定義(macro)。它的好處只對(duì)短小的函數(shù)有效,這種情況下因?yàn)楸苊饬苏{(diào)用函數(shù)的一些常規(guī)操作的時(shí)間(overhead),如參數(shù)堆棧操作的時(shí)間,所以編譯結(jié)果的運(yùn)行代碼會(huì)更快一些。調(diào)用函數(shù)的時(shí)候并不需要寫(xiě)關(guān)鍵字inline ,只有在函數(shù)聲明前需要寫(xiě)。
4、將數(shù)組作為參數(shù)傳入函數(shù),傳的是引用而不是值。void procedure (int myarray[ ][3][4])
九、函數(shù)指針的用法
使用函數(shù)指針的幾種方法:(1)簡(jiǎn)單調(diào)用函數(shù)指針;void (pfunc)(int);pfunc=callback_funcname;callback_funcname(1);其中聲明函數(shù)指針原型的代碼可以在調(diào)用處寫(xiě),也可以寫(xiě)成全局的。這種方法使用簡(jiǎn)單,適用于臨時(shí)調(diào)用。(2)使用typedef調(diào)用函數(shù)指針:typedef void(PFUNC)(int);PFUNC pfunc;pfunc=callback_funcname;callback_funcname(1);這種方法適用于多次調(diào)用,先全局定義PFUNC,再在每個(gè)調(diào)用的地方聲明臨時(shí)變量后調(diào)用。(3)C++類(lèi)中調(diào)用成員函數(shù)指針(不使用typedef):void (MyClass::pfunc)(int);pfunc=&MyClass::callback_funcname;(this->callback_funcname)(1);和方法1類(lèi)似,注意語(yǔ)法的不同。(4)C++類(lèi)中調(diào)用成員函數(shù)指針(使用用typedef):typedef void(PFUNC)(int); //在類(lèi)中typedefPUNC pfunc;pfunc=&MyClass::callback_funcname;(this->callback_funcname)(1);和方法2類(lèi)似,注意語(yǔ)法的不同。
十、typedef的不常用用法
typedef的一般用法是:
typedef int UINT32;
但用來(lái)定義一個(gè)數(shù)組類(lèi)型或指針函數(shù)時(shí),比較特殊:
typedef char CARRAY[32]; //定義了一個(gè)CARRAY的類(lèi)型,代表char[32]
typedef void(*PFUN)(int); //定義了一個(gè)指向指針函數(shù)的變量類(lèi)型,函數(shù)原型為void xxx(int yyy);
十一、類(lèi)的private/protected/public屬性
1、類(lèi)的成員如果沒(méi)有指定訪問(wèn)域,默認(rèn)是private的。
2、標(biāo)識(shí)符protected 與 private類(lèi)似,它們的唯一區(qū)別在繼承時(shí)才表現(xiàn)出來(lái)。當(dāng)定義一個(gè)子類(lèi)的時(shí)候,基類(lèi)的protected 成員可以被子類(lèi)的其它成員所使用,然而private 成員就不可以。
3、public/protected/private繼承的區(qū)別:(1)public繼承:父類(lèi)的public依然是public,protected依然是protected,private不可訪問(wèn);(2)protected繼承:父類(lèi)的public稱(chēng)為protected,protected稱(chēng)為private;(3)private繼承:父類(lèi)的所有成員全部變成private。
十二、關(guān)于空類(lèi)
編譯器為一個(gè)空類(lèi)提供哪些默認(rèn)函數(shù)?
1、C++編譯器會(huì)提供默認(rèn)的構(gòu)造函數(shù),析構(gòu)函數(shù), 拷貝構(gòu)造函數(shù)和拷貝賦值操作符(請(qǐng)參考著名的Effective C++的第三版的第5條)當(dāng)我們定義一個(gè)class而沒(méi)有明確定義構(gòu)造函數(shù)的時(shí)候,編譯器會(huì)自動(dòng)假設(shè)兩個(gè)重載的構(gòu)造函數(shù) (默認(rèn)構(gòu)造函數(shù)"default constructor" 和復(fù)制構(gòu)造函數(shù)"copy constructor")。拷貝構(gòu)造函數(shù)是一個(gè)只有一個(gè)參數(shù)的構(gòu)造函數(shù)(原型:ClassName(ClassName &cn){};),該參數(shù)是這個(gè)class的一個(gè)對(duì)象,這個(gè)函數(shù)的功能是將被傳入的對(duì)象(object)的所有非靜態(tài)(non-static)成員變量的值都復(fù)制給自身這個(gè)object。必須注意:這兩個(gè)默認(rèn)構(gòu)造函數(shù)(empty construction 和 copy constructor )只有在沒(méi)有其它構(gòu)造函數(shù)被明確定義的情況下才存在。一個(gè)類(lèi)包含一個(gè)對(duì)賦值操作符assignation operator (=)的默認(rèn)定義,該操作符用于兩個(gè)同類(lèi)對(duì)象之間。這個(gè)操作符將其參數(shù)對(duì)象(符號(hào)右邊的對(duì)象) 的所有非靜態(tài) (non-static) 數(shù)據(jù)成員復(fù)制給其左邊的對(duì)象。2、用class obj;的方式聲明一個(gè)對(duì)象,如果構(gòu)造函數(shù)沒(méi)有參數(shù),或只有默認(rèn)構(gòu)造函數(shù),后面不能加(),因?yàn)榫幾g器會(huì)誤以為這是一個(gè)沒(méi)有參數(shù)的函數(shù)聲明;3、如果任何其它有任意參數(shù)的構(gòu)造函數(shù)被定義了,默認(rèn)構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)就都不存在了。在這種情況下,如果你想要有empty construction和copy constructor ,就必需要自己定義它們。4、對(duì)基本類(lèi)型,在c++里面,為了模板template,規(guī)定他們可以使用類(lèi)似于類(lèi)的默認(rèn)構(gòu)造函數(shù)的方式(僅僅是類(lèi)似的方式而已) 賦初始值0。這叫做基本類(lèi)型的顯示初始化, 請(qǐng)參考 C++標(biāo)準(zhǔn)程序庫(kù)(The C++ Standard Library)的14頁(yè),2.2.2 基本型別的顯示初始化,書(shū)中舉的例子就是int i1;//未初始化int i2 = int(); //初始化為0
sizeof一個(gè)空類(lèi)等于多少?
sizeof一個(gè)空類(lèi)返回1。所謂類(lèi)的實(shí)例化就是在內(nèi)存中分配一塊地址,每個(gè)實(shí)例在內(nèi)存中都有獨(dú)一無(wú)二的地址。同樣空類(lèi)也會(huì)被實(shí)例化,所以編譯器會(huì)給空類(lèi)隱含的添加一個(gè)字節(jié),這樣空類(lèi)實(shí)例化之后就有了獨(dú)一無(wú)二的地址了。所以空類(lèi)的sizeof為1。C++編譯器不允許對(duì)象為零長(zhǎng)度。試想一個(gè)長(zhǎng)度為0的對(duì)象在內(nèi)存中怎么存放?怎么獲取它的地址?為了避免這種情況,C++強(qiáng)制給這種類(lèi)插入一個(gè)缺省成員,長(zhǎng)度為1。如果有自定義的變量,變量將取代這個(gè)缺省成員。
十三、繼承或多重繼承情況下構(gòu)造函數(shù)的調(diào)用順序
(1)如果聲明為Derive: public Super1, public Super2{AnotherClass m_obj;}; 構(gòu)造函數(shù)的調(diào)用順序是:Super1, Super2, AnotherClass, Derive.(2)如果父類(lèi)有默認(rèn)構(gòu)造函數(shù),或沒(méi)有參數(shù)的構(gòu)造函數(shù),不需要在子類(lèi)的構(gòu)造函數(shù)定義中顯式調(diào)用父類(lèi)構(gòu)造函數(shù),否則需要調(diào)用。成員對(duì)象也是一樣道理。以上面的例子說(shuō)明,Derive的構(gòu)造函數(shù)寫(xiě)法是:Derive(int i): Super1(i), Super2(i), m_obj(1){...}注意,成員對(duì)象初始化時(shí)應(yīng)該指明對(duì)象名稱(chēng),而不是類(lèi)名。
析構(gòu)函數(shù)的調(diào)用順序應(yīng)該是依次反過(guò)來(lái)的。
十四、虛函數(shù)、純虛函數(shù)和抽象類(lèi)、虛析構(gòu)函數(shù)
虛函數(shù)的作用和運(yùn)行原理
(1)多態(tài)是面向?qū)ο缶幊讨械暮诵母拍睿褪钦f(shuō)一個(gè)基類(lèi)類(lèi)型的指針實(shí)際上可能指向的是一個(gè)子類(lèi)對(duì)象。只有在運(yùn)行時(shí)才能根據(jù)實(shí)際情況來(lái)決定執(zhí)行哪個(gè)函數(shù),也就是動(dòng)態(tài)聯(lián)編。和動(dòng)態(tài)聯(lián)編對(duì)應(yīng)的是靜態(tài)聯(lián)編,也就是說(shuō)在編譯時(shí)就決定了調(diào)用哪個(gè)函數(shù)。為了實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編,必須將父類(lèi)的函數(shù)聲明為virtual。如果沒(méi)有聲明為virtual,可能得到的結(jié)果不是預(yù)期中的。對(duì)于析構(gòu)函數(shù)而言,虛函數(shù)保證子類(lèi)和父類(lèi)的析構(gòu)函數(shù)都會(huì)被執(zhí)行。參考:http://jiamingjun03.blog.163.com/blog/static/11687677620099297435263/(2)對(duì)于包含了至少一個(gè)虛函數(shù)的類(lèi)(或其父類(lèi)包含虛函數(shù)),編譯器需要為這個(gè)類(lèi)增加4個(gè)字節(jié),用來(lái)保存指向虛函數(shù)表VTABLE的指針。
純虛函數(shù)和抽象類(lèi)
包含了純虛函數(shù)的類(lèi)不能被直接實(shí)例化,可以稱(chēng)為抽象類(lèi)。定義方法:virtual void func()=0;子類(lèi)override一個(gè)虛函數(shù),不一定要加virtual關(guān)鍵字。
什么情況下需要指定析構(gòu)函數(shù)為virtual?
(1)析構(gòu)函數(shù)不一定需要定義為虛函數(shù),只有當(dāng)這個(gè)類(lèi)要作為其他類(lèi)的父類(lèi)使用時(shí),才需要定義為虛函數(shù)。如果父類(lèi)的析構(gòu)函數(shù)沒(méi)有定義為虛函數(shù),則子類(lèi)對(duì)象銷(xiāo)毀時(shí),父類(lèi)析構(gòu)函數(shù)不會(huì)被調(diào)用。(2)對(duì)于一個(gè)抽象類(lèi),析構(gòu)函數(shù)可以被定義為純虛的。(3)父類(lèi)和子類(lèi)之間的虛函數(shù)動(dòng)態(tài)聯(lián)編不會(huì)因?yàn)閜rivate發(fā)生影響。(4)一個(gè)類(lèi)的虛函數(shù)在它自己的構(gòu)造函數(shù)和析構(gòu)函數(shù)中被調(diào)用的時(shí)候,它們就變成普通函數(shù)了,不“虛”了。也就是說(shuō)不能在構(gòu)造函數(shù)和析構(gòu)函數(shù)中讓自己“多態(tài)”。(5)在虛函數(shù)和純虛函數(shù)的定義中不能有static標(biāo)識(shí)符,原因很簡(jiǎn)單,被static修飾的函數(shù)在編譯時(shí)候要求前期bind,然而虛函數(shù)卻是動(dòng)態(tài)綁定(run-time bind),而且被兩者修飾的函數(shù)生命周期(life recycle)也不一樣。
十五、多重繼承情況下如何引用父類(lèi)的同名成員?
重繼承情況下,如果多個(gè)基類(lèi)有同名成員,引用方法是:
pDeriveObj->BaseClass1::Member;
十六、運(yùn)算符重載
語(yǔ)法:
Type Type::operator +(const Type &i){}
十七、友元
友元可以實(shí)現(xiàn)外部對(duì)private和protected成員的訪問(wèn)。有兩種實(shí)現(xiàn):(1)友元函數(shù)。語(yǔ)法:在函數(shù)聲明前加上friend。友元函數(shù)并不是類(lèi)的成員函數(shù),實(shí)現(xiàn)函數(shù)體或調(diào)用函數(shù)時(shí)不加ClassName::。(2)友元類(lèi)。在類(lèi)的聲明中加入:friend class VisitorClass;友元不會(huì)被子類(lèi)繼承。
十八、模板
函數(shù)模板
實(shí)現(xiàn)語(yǔ)法:
在函數(shù)的聲明和實(shí)現(xiàn)前加上template<typename T> ,(typename和class等價(jià)),可以寫(xiě)在一行里面,也可以分成兩行寫(xiě),注意>后面沒(méi)有分號(hào)。如果聲明和實(shí)現(xiàn)分開(kāi)寫(xiě),兩個(gè)地方都要寫(xiě)上template<typename T>。(1)一行代碼中同時(shí)聲明并實(shí)現(xiàn)函數(shù)template <typename T>void func(T t1, T t2)
{...};(2)分兩行代碼聲明并實(shí)現(xiàn)函數(shù)template <class T>void func(T t1, T t2){...};(3)在兩個(gè)地方分別聲明和實(shí)現(xiàn)函數(shù)template <class T>void func(T t1, T t2);...template <class T>void func(T t1, T t2){...}
引用語(yǔ)法:
func<int>(5, 6);
類(lèi)模板
聲明方法:
類(lèi)模板可以實(shí)現(xiàn)在一個(gè)類(lèi)中有一個(gè)通用類(lèi)型的成員變量。
template <class T> class ClassName
{public:
T *m_pVariable;
};
引用方法:
ClassName<int> obj;
模板特殊化
模板特殊化可以專(zhuān)門(mén)為某種數(shù)據(jù)類(lèi)型定義特殊的行為。類(lèi)的定義必須和通用的模板類(lèi)完全一致,除了用專(zhuān)門(mén)語(yǔ)法,并將T修改為專(zhuān)門(mén)的類(lèi)型,并定義特殊行為。template<> class<int>{定義通用函數(shù),定義特殊函數(shù)};
定義模板的默認(rèn)值template <class T = char> // 有一個(gè)默認(rèn)值。
模板的參數(shù)值
除了模板參數(shù)前面跟關(guān)鍵字class 或 typename 表示一個(gè)通用類(lèi)型外,函數(shù)模板和類(lèi)模板還可以包含其它不是代表一個(gè)類(lèi)型的參數(shù),例如代表一個(gè)常數(shù),這些通常是基本數(shù)據(jù)類(lèi)型的。
二十、類(lèi)型轉(zhuǎn)換和C++高級(jí)類(lèi)型轉(zhuǎn)換
基本類(lèi)型強(qiáng)轉(zhuǎn)有兩種寫(xiě)法:
int i;float f = 3.14;i = (int) f;i = int ( f );
高級(jí)類(lèi)型轉(zhuǎn)換
ANSI-C++ 標(biāo)準(zhǔn)定義了4種新的類(lèi)型轉(zhuǎn)換操作符: reinterpret_cast, static_cast, dynamic_cast 和const_cast。
reinterpret_cast可以將一個(gè)指針轉(zhuǎn)換為任意其它類(lèi)型的指針。ClassA* pa;ClassB* pb=reinterpret_cast<ClassB*>pa;
static_cast可以執(zhí)行所有能夠隱含執(zhí)行的類(lèi)型轉(zhuǎn)換,以及它們的反向操作(即使這種方向操作是不允許隱含執(zhí)行的)。用于類(lèi)的指針,也就是說(shuō),它允許將一個(gè)引申類(lèi)的指針轉(zhuǎn)換為其基類(lèi)類(lèi)型(這是可以被隱含執(zhí)行的有效轉(zhuǎn)換),同時(shí)也允許進(jìn)行相反的轉(zhuǎn)換:將一個(gè)基類(lèi)轉(zhuǎn)換為一個(gè)引申類(lèi)類(lèi)型。不會(huì)檢查被轉(zhuǎn)換的基類(lèi)是否真正完全是目標(biāo)類(lèi)型的。Derive* pa;Super* pb;pa = static_cast<Derive> pb; pb = static_cast<Super> pa;static_cast除了能夠?qū)︻?lèi)指針進(jìn)行操作,還可以被用來(lái)進(jìn)行類(lèi)中明確定義的轉(zhuǎn)換,以及對(duì)基本類(lèi)型的標(biāo)準(zhǔn)轉(zhuǎn)換:double d=3.14159265;int i = static_cast<int>(d);
dynamic_cast 完全被用來(lái)進(jìn)行指針的操作。它可以用來(lái)進(jìn)行任何可以隱含進(jìn)行的轉(zhuǎn)換操作以及它們被用于多態(tài)類(lèi)情況下的方向操作。然而與static_cast不同的是, dynamic_cast 會(huì)檢查后一種情況的操作是否合法,也就是說(shuō)它會(huì)檢查類(lèi)型轉(zhuǎn)換操作是否會(huì)返回一個(gè)被要求類(lèi)型的有效的完整的對(duì)象。在不合法的情況下,如果用于指針,將返回NULL;如果用于引用,拋出異常。Derive* pa = new Derive();Super* pb = new Super();pa = dynamic_cast<Derive> pb; //失敗,返回NULLpb = dynamic_cast<Super> pa; //成功
const_cast類(lèi)型轉(zhuǎn)換對(duì)常量const 進(jìn)行設(shè)置或取消操作。class C {};const C * a = new C;C * b = const_cast<C*> (a);
typeid (object_pointer)這個(gè)操作符返回一個(gè)類(lèi)型為type_info的常量對(duì)象指針,這種類(lèi)型定義在標(biāo)準(zhǔn)頭函數(shù)中。type_info::name()返回對(duì)象的類(lèi)名。
二十一、命名空間
定義一個(gè)命名空間:
namespace ns1{...}
設(shè)置默認(rèn)命名空間:
using namespace ns1;
引用其他命名空間的類(lèi)型:
ns2::variable = xx;
二十二、預(yù)處理命令
undef 完成與 #define相反的工作,它取消對(duì)傳入的參數(shù)的宏定義
ifdef, #ifndef, #if, #endif, #else and #elif
指令#line 可以使我們對(duì)這兩點(diǎn)進(jìn)行控制,也就是說(shuō)當(dāng)出錯(cuò)時(shí)顯示文件中的行數(shù)以及我們希望顯示的文件名。它的格式是:#line number "filename"下面這段代碼將會(huì)產(chǎn)生一個(gè)錯(cuò)誤,顯示為在文件"assigning variable", line 1 。#line 1 "assigning variable"int a?;
這個(gè)指令將中斷編譯過(guò)程并返回一個(gè)參數(shù)中定義的出錯(cuò)信息#error
這個(gè)指令是用來(lái)對(duì)編譯器進(jìn)行配置的,針對(duì)你所使用的平臺(tái)和編譯器而有所不同。#pragma
二十三、預(yù)定義宏
LINE 整數(shù)值,表示當(dāng)前正在編譯的行在源文件中的行數(shù)。FILE 字符串,表示被編譯的源文件的文件名。DATE 一個(gè)格式為 "Mmm dd yyyy" 的字符串,存儲(chǔ)編譯開(kāi)始的日期。TIME 一個(gè)格式為 "hh:mm:ss" 的字符串,存儲(chǔ)編譯開(kāi)始的時(shí)間。__cplusplus 整數(shù)值,所有C++編譯器都定義了這個(gè)常量為某個(gè)值。如果這個(gè)編譯器是完全遵守C++標(biāo)準(zhǔn)的,它的值應(yīng)該等于或大于199711L,具體值取決于它遵守的是哪個(gè)版本的標(biāo)準(zhǔn)。
學(xué)習(xí)過(guò)程中遇到什么問(wèn)題或者想獲取學(xué)習(xí)資源的話,歡迎加入學(xué)習(xí)交流群
639368839,我們一起學(xué)C/C++!