1.如果要在多個(gè)變量中使用一個(gè)const變量,可以在一個(gè)頭文件中定義,然后再其他文件中include<> 或者可以在c++的源文件中定義,然后才其他源文件中extern
2.標(biāo)準(zhǔn)頭文件用#inclue<>
自定義的頭文件用 #include “”
3.預(yù)防多次包含偶同一頭文件
#ifndef SALE
#define SALE //表示接受一個(gè)名字并定義該名字為預(yù)處理器變量
define of class and relate function
#endif
4.迭代器iterator的begin()操作返回的迭代器容器的第一個(gè)元素,end()返回容器的迭代器指向容器最后一個(gè)元素的下一個(gè)元素
5.如果不改變?nèi)萜鞯膬?nèi)容,只做讀操作,使用const_iterator,
區(qū)別于const 的iterator,聲明一個(gè)const 迭代器,必須初始化,且一旦初始化后就不能改變。
6.迭代器的算術(shù)操作
iter + n 產(chǎn)生一個(gè)新的迭代器,位置指向iter指向元素之后n各的位置
iter1 - ite4r2 返回兩個(gè)迭代器對(duì)象的距離
7.任何改變vector長度的操作都會(huì)使已存在的迭代器失效,如push_back
8.指針的初始化
0
類型匹配的對(duì)象的地址
另一對(duì)象之后的下一地址
同類型的另一個(gè)有效指針
9.void* 指針可以保存任何對(duì)象的地址
表明指針只與一個(gè)地址相關(guān),并不知道地址上所存的對(duì)象類型,不能用 void *操縱它所指的對(duì)象
10. #include <cstddef>
size_t unsigned 用來指明數(shù)組的長度
ptrdiff_t unsigned 用來指明指針的距離
11
指向const對(duì)象的指針
const double * cptr;
并不是指針本身是const的,而是所指的對(duì)象是const的,不能通過cptr修改所指對(duì)象的值,也不能把const對(duì)象的地址賦值給非const指針,
const 指針
int *const p = #
必須在定義時(shí)初始化。
指向const 對(duì)象的const 指針
const double *const ptr = π
12.string .c_str()返回const char 類型的指針
13sizeof返回size_t類型,計(jì)算數(shù)組元素的個(gè)數(shù)
n = sizeof(arr)/sizeof(*arr);
14.算術(shù)轉(zhuǎn)換
int + double -> double
float + double -> double
int = double -> int
float = double -> float
chat + float -> float
short + long -> long
int + unsigned long -> unsigned long
15 強(qiáng)制類型轉(zhuǎn)換
const_cast<>()轉(zhuǎn)換掉表達(dá)式的const性質(zhì)
static_cast<>()很適合將一個(gè)較大的類型轉(zhuǎn)換成一個(gè)較小的類型。
16.函數(shù)的參數(shù)
int fun(int *p) 可以改變指針?biāo)傅膶?duì)象的值
int fun(int *p) 如果保護(hù)指針?biāo)傅膮?shù)的值,要加上const int f(const int *p)
void fun(const int i) 不能改變實(shí)參的的局部副本,can read but can't write to i ;
17 引用
引用形參直接關(guān)聯(lián)到所綁定的對(duì)象.void swap(int &a , int &b)
像函數(shù)傳遞大型對(duì)象的時(shí)候,利用const引用避免復(fù)制,
復(fù)制龐大而復(fù)雜的值有昂貴的開銷。為了避免傳遞副本的開銷,可將形參指定為引用類型。對(duì)引用形參的任何修改會(huì)直接影響實(shí)參本身。應(yīng)將不需要修改相應(yīng)實(shí)參的引用形參定義為 const 引用 |
非const引用的形參只能與同類型的非const的對(duì)象關(guān)聯(lián).
18 數(shù)組形參的定義
void f (int *)
void f (int [])
void f (int [10])
以上三種都等價(jià)為 void f(int *)
19 通過引用傳遞數(shù)組
void f(int (&arr)[100])
傳遞的是數(shù)組的引用本身,數(shù)組大小成為形參和實(shí)參的一部分,編譯器會(huì)檢查兩者是否匹配。
29返回值
返回非引用類型,函數(shù)會(huì)在調(diào)用出將函數(shù)返回值復(fù)制給臨時(shí)對(duì)象。
返回引用返回的是對(duì)象本身,不要返回局部對(duì)象的引用
const string &f(const string & s)
{ string ret = s; return ret ;}//err
不要返回指向局部對(duì)象的指針(懸垂指針)
30默認(rèn)實(shí)參
string ScreenInit(string::size_type with = 24 ,string::size_type heigth = 59 );
string screen = ScreenInit();
screen = ScreenInit(20)
screen = ScreenInit(20,90)
40將函數(shù)指定為內(nèi)聯(lián)是建議編譯器在調(diào)用點(diǎn)直接把函數(shù)代碼展開,內(nèi)聯(lián)函數(shù)避免函數(shù)調(diào)用的開銷,內(nèi)聯(lián)函數(shù)必須在頭文件中定義,
|
41const成員函數(shù),在參數(shù)列表后面加上const ,則const成員函數(shù)不能改變調(diào)用該函數(shù)的對(duì)象。
42在局部聲明的變量名字將屏蔽在全局生命的同名名字,這個(gè)性質(zhì)對(duì)函數(shù)名也同樣成立。
43.函數(shù)指針
bool (*pf)(const string &, const string &); typedef bool (*cmpFcn)(const string &, const string &); |
圓括號(hào)不可以省略。 函數(shù)指針只能通過同類型的函數(shù)或函數(shù)指針或 0 值常量表達(dá)式進(jìn)行初始化或賦值 |
|
|
44.IO對(duì)象
IO對(duì)象不可復(fù)制或賦值,不可以存在vector等容器中.
形參或返回類型也不能為流類型。如果需要傳遞或返回 IO 對(duì)象,則必須傳遞或返回指向該對(duì)象的指針或引用 ofstream &print(ofstream&); 45.輸出緩沖區(qū)的管理
統(tǒng)將字符串字面值存儲(chǔ)在與流 os 關(guān)聯(lián)的緩沖區(qū)中。下面幾種情況將導(dǎo)致緩沖區(qū)的內(nèi)容被刷新,即寫入到真實(shí)的輸出設(shè)備或者文件
程序正常結(jié)束。作為 main 返回工作的一部分,將清空所有輸出緩沖區(qū)。 在一些不確定的時(shí)候,緩沖區(qū)可能已經(jīng)滿了,在這種情況下,緩沖區(qū)將會(huì)在寫下一個(gè)值之前刷新。 用操縱符顯式地刷新緩沖區(qū),例如行結(jié)束符 endl。 在每次輸出操作執(zhí)行完后,用 unitbuf 操作符設(shè)置流的內(nèi)部狀態(tài),從而清空緩沖區(qū)。 可將輸出流與輸入流關(guān)聯(lián)(tie)起來。在這種情況下,在讀輸入流時(shí)將刷新其關(guān)聯(lián)的輸出緩沖區(qū)。 cout << "hi!" << flush; // flushes the buffer; adds no data cout << "hi!" << ends; // inserts a null, then flushes the buffer cout << "hi!" << endl; // inserts a newline, then flushes the buffer unitbuf 操縱符。這個(gè)操縱符在每次執(zhí)行完寫操作后都刷新流: cout << unitbuf << "first" << " second" << nounitbuf; 當(dāng)輸入流與輸出流綁在一起時(shí),任何讀輸入流的嘗試都將首先刷新其輸出流關(guān)聯(lián)的緩沖區(qū)。標(biāo)準(zhǔn)庫將cout 與 cin 綁在一起,因此語句:cin >> ival;導(dǎo)致 cout 關(guān)聯(lián)的緩沖區(qū)被刷新。
|
|
|
|
46stringstream 可將多種數(shù)據(jù)格式與string類型進(jìn)行自動(dòng)轉(zhuǎn)化
47成員函數(shù):
在類內(nèi)部定義的函數(shù)默認(rèn)為inline. 將關(guān)鍵字const加在形參列表之后,const成員函數(shù)不能改變其所操作對(duì)象的數(shù)據(jù)成員。 48const成員函數(shù)返回*this
普通非const成員函數(shù)的this是一個(gè)指向類類型的const指針,可以改變this指向的值,不能改變this所保存的地址,而const成員函數(shù),this的類型是一個(gè)指向const類型對(duì)象的const指針。const成員函數(shù)只能返回*this作為const 引用, 50mutable數(shù)據(jù)成員
將類成員聲明為mutable,任意const對(duì)象,或者const函數(shù)丟可以改變它的值 51構(gòu)造函數(shù)
不管成員是否在構(gòu)造函數(shù)中顯示初始化,類類型的數(shù)據(jù)成員總是在初始化階段初始化。在構(gòu)造函數(shù)初始化列表沒有顯示提及的每個(gè)成員,運(yùn)行該類型的默認(rèn)構(gòu)造函數(shù),內(nèi)置貨符合類型的初始值依賴于對(duì)象的作用域:在局部作用域這些函數(shù)不被初始化,在全局作用域被初始化為0. 沒有默認(rèn)構(gòu)造函數(shù)的類類型成員,以及const或引用類型的成員,都必須在初始化列表進(jìn)行初始化。 按照與聲明一致的次序編寫構(gòu)造函數(shù)初始化列表是個(gè)好主意。 52默認(rèn)構(gòu)造函數(shù)
定義一個(gè)對(duì)象是沒有提供初始化式,就是使用默認(rèn)構(gòu)造函數(shù),為所有形參提供默認(rèn)實(shí)參的構(gòu)造函數(shù)也定義了默認(rèn)構(gòu)造函數(shù) 53static成員和成員函數(shù)
非static成員存在于每個(gè)類類型的對(duì)象中,而static成員獨(dú)立于該類的任意對(duì)象而存在,美國各static數(shù)據(jù)成員是與該類關(guān)聯(lián)的對(duì)象。 static成員函數(shù)沒有this形參,可以直接訪問所屬類的static成員,但是不能直接使用費(fèi)static成員 54復(fù)制構(gòu)造函數(shù)
復(fù)制構(gòu)造函數(shù)只有一個(gè)形參,該形參(常用const修飾)是對(duì)該類類型的引用,當(dāng)定義一個(gè)新對(duì)象并用一個(gè)同類型的對(duì)象對(duì)他進(jìn)行初始化的時(shí)候,是顯式得使用復(fù)制構(gòu)造函數(shù),將該類型的對(duì)象傳遞給函數(shù)uo從函數(shù)返回該類型的對(duì)象的時(shí)候,是隱式得使用復(fù)制構(gòu)造函數(shù)。 string null_book = "9-999-99999-9"; // copy-initialization string dots(10, '.'); // direct-initialization string empty_copy = string(); // copy-initialization string empty_direct; // direct-initializat |
| 55為了避免復(fù)制,類必須顯式聲明復(fù)制構(gòu)造函數(shù)為private 然而這樣類的友元和成員仍可以復(fù)制,如果要連友元和成員的復(fù)制也禁止,可以定義一個(gè)private的復(fù)制構(gòu)造函數(shù)但不對(duì)其定義。
56賦值操作符重載 當(dāng)操作符為成員函數(shù)的時(shí)候,第一個(gè)操作數(shù)隱式地綁定到this指針,即this綁定到左操作數(shù)的指針,右操作數(shù)一般為const傳遞的引用,復(fù)制操作返回同一類型的引用。
57析構(gòu)函數(shù) 析構(gòu)函數(shù)沒有參數(shù)也不能重載,即使我們編寫了自己的析構(gòu)函數(shù),合成析構(gòu)函數(shù)仍然運(yùn)行,合成析構(gòu)函數(shù)不刪除指針成員所指向的對(duì)象,合成析構(gòu)函數(shù)按對(duì)象創(chuàng)建的時(shí)間逆序撤銷每個(gè)非static成員。
58重載操作符 賦值(=)、下標(biāo)([])、調(diào)用(())和成員訪問箭頭(->)等操作符必須定義為成員,將這些操作符定義為非成員函數(shù)將在編譯時(shí)標(biāo)記為錯(cuò)誤 | |
|
|
復(fù)合賦值操作通常定義為類的成員,但不一定要定義成類的成員
改變對(duì)象狀態(tài)或與給定類型緊密聯(lián)系的操作,如自增,自減和解引用操作,都應(yīng)該定義為類的成員
對(duì)稱的操作符,如算術(shù)操作符,相等操作度關(guān)系操作符和類操作符,最好定義為普通非成員函數(shù)
IO操作必須為非成員函數(shù)
賦值必須返回對(duì)*this的引用
operator + 返回一個(gè)對(duì)象,而operator +=返回一個(gè)引用
定義下標(biāo)操作符[]時(shí),一般定義兩個(gè)版本,一個(gè)為非const成員返回引用,另一個(gè)為const成員返回const引用。
class S
{
public :
int &operator[] (const size_t);
const int &operator[]( const size_t)const;
}
59定義轉(zhuǎn)換和操作符
(1)不要定義相互轉(zhuǎn)換的類,機(jī)如果類Foo具有接受類 Bar的對(duì)象的構(gòu)造函數(shù),不要再為類Bar定義到類型Foo的構(gòu)造函數(shù)
(2)避免到內(nèi)置算術(shù)類型的轉(zhuǎn)換,具體而言,如果定義到算術(shù)類型的轉(zhuǎn)換,不要定義接受算術(shù)類型的操作符的重載版本,如果用戶需要使用這些操作符,轉(zhuǎn)換操作副將轉(zhuǎn)換你所定義的類型的對(duì)象,然后可以使用內(nèi)置操作符
不要定義轉(zhuǎn)換到一個(gè)以上算術(shù)類型的轉(zhuǎn)換,讓標(biāo)準(zhǔn)抓包換提供到其他算術(shù)類型的轉(zhuǎn)換
60基類成員函數(shù)
成員函數(shù)默認(rèn)為非虛函數(shù),對(duì)f非虛函數(shù)的調(diào)用在編譯時(shí)確定,除了構(gòu)造函數(shù),其他非static成員函數(shù)都可以是虛函數(shù),虛函數(shù)運(yùn)行時(shí)動(dòng)態(tài)綁定,
61訪問控制和繼承
public private和protect
用戶可以訪問類的public成員,不能訪問private成員
private成員只能由基類的成員或友元訪問
派生類對(duì)象對(duì)基類的public和private成員的訪問權(quán)限和程序中任意其他部分一樣,可以訪問public不能訪問private。
protect成員不能被類的用戶訪問,可以被類的派生類訪問,派生類只能通過派生類的對(duì)象訪問基類的protect成員,派生類對(duì)基類類型對(duì)象的proteced成員沒有訪問權(quán)限
62虛函數(shù)動(dòng)態(tài)綁定
出發(fā)動(dòng)態(tài)綁定的兩個(gè)條件:1.指定為virtual,2,必須通過基類類型的引用或指針進(jìn)行調(diào)用
63派生類虛函數(shù)調(diào)用基類版本的時(shí)候,必須顯式使用作用域操作符
64虛函數(shù)的基類版本和派生類版本使用不同的默認(rèn)實(shí)參,通過基類的指針或引用調(diào)用,但實(shí)際執(zhí)行的是派生類的版的時(shí)候會(huì)出問題,因?yàn)樘摵瘮?shù)基類版本定義的默認(rèn)實(shí)參會(huì)傳給派生類的版本。
65pubilc,private,和protect繼承
public inheritance :基類的public成員為派生類的public成員,基類的protect成員為派生類的protect成員
private inheritance:基類的所有成員在派生類中為private成員
protect inheritance:基類的public成員和protect成員在派生類中為protect成員
派生類不能訪問基類的protect成員
類的默認(rèn)的繼承為private,struct默認(rèn)的繼承為public的
65繼承和static成員
如果基類定義了static成員,則整個(gè)繼承層次中只有一個(gè)這樣的成員,無論基類派生出多少個(gè)派生類,沒個(gè)static成員只有一個(gè)實(shí)例
66派生類到基類的轉(zhuǎn)換
可以用派生類的對(duì)象對(duì)基類對(duì)象進(jìn)行賦值或初始化
引用轉(zhuǎn)換不同于轉(zhuǎn)換對(duì)象,將派生類對(duì)象傳給希望接受基類對(duì)象的函數(shù)是,該派生類對(duì)象的基類部分被復(fù)制到形參
67從基類到派生類的自動(dòng)轉(zhuǎn)換時(shí)不存在的
68如果派生類顯示定義復(fù)制構(gòu)造函數(shù)或賦值操作符,則該定義將完全覆蓋默認(rèn)定義,必須顯示的調(diào)用繼承的復(fù)制構(gòu)造函數(shù)和賦值操作符對(duì)基類成分以及類自己的成員進(jìn)行復(fù)制或賦值。
class Derived{
public:
Derived(const derived &d):Base(d) { other menber initialization}
}
69即使沒有工作要做,繼承層次的跟類也應(yīng)該定義一個(gè)虛析構(gòu)函數(shù)
70構(gòu)造函數(shù)不能是虛函數(shù),復(fù)制操作符最好不要是虛函數(shù)(虛函數(shù)的形參列表等必須相同,會(huì)引起混淆)
71如果在構(gòu)造函數(shù)或者析構(gòu)函數(shù)效用虛函數(shù),則調(diào)用的是為構(gòu)造函數(shù)或析構(gòu)函數(shù)自身類型定義的版本。
72與基類成員同名的派生類成員將屏蔽對(duì)基類成員的直接訪問,成員函數(shù)名也一樣。
73重載成員函數(shù)
如果派生類定義了重載成員函數(shù),則通過派生類類型之unengfangwen派生類中重定義的那些成員,如果要訪問,加個(gè)using聲明(?)
74容器與繼承
如果定義了一個(gè)基類類型的容器,派生類對(duì)象在賦值給容器的時(shí)候,對(duì)象的派生屬性會(huì)被切掉,只保留基類的成分
75c++繼承如火確定函數(shù)調(diào)用
1. | 首先確定進(jìn)行函數(shù)調(diào)用的對(duì)象、引用或指針的靜態(tài)類型。
| 2. | 在該類中查找函數(shù),如果找不到,就在直接基類中查找,如此循著類的繼承鏈往上找,直到找到該函數(shù)或者查找完最后一個(gè)類。如果不能在類或其相關(guān)基類中找到該名字,則調(diào)用是錯(cuò)誤的。
| 3. | 一旦找到了該名字,就進(jìn)行常規(guī)類型檢查,查看如果給定找到的定義,該函數(shù)調(diào)用是否合法。
| 4. | 假定函數(shù)調(diào)用合法,編譯器就生成代碼。如果函數(shù)是虛函數(shù)且通過引用或指針調(diào)用,則編譯器生成代碼以確定根據(jù)對(duì)象的動(dòng)態(tài)類型運(yùn)行哪個(gè)函數(shù)版本,否則,編譯器生成代碼直接調(diào)用函數(shù)。
|
|
|
76模板
模板形參是const引用
函數(shù)體中的測(cè)試之用 < 比較
多個(gè)類型形參的實(shí)參必須完全匹配
77異常
異常通過拋出(throw)對(duì)象引發(fā),執(zhí)行throw的時(shí)候,不會(huì)執(zhí)行在throw后面的語句,而是將控制從throw轉(zhuǎn)移到匹配的chatch。
處理異常的時(shí)候會(huì)四方局部存儲(chǔ),被拋出的對(duì)象不能再局部存儲(chǔ),而是用tw表達(dá)式出事話一個(gè)床位異常對(duì)象的特殊對(duì)象。
當(dāng)拋出一個(gè)表達(dá)式的時(shí)候,被拋出的對(duì)象的靜態(tài)編譯時(shí)的類型將決定異常對(duì)象的類型,最好不要拋出指針
當(dāng)catch結(jié)束的時(shí)候,在緊接在與該try塊相關(guān)的最后一個(gè)cahtch子句只有的點(diǎn)繼續(xù)執(zhí)行
一個(gè)快可以通過調(diào)用new動(dòng)態(tài)分配內(nèi)存,如果該塊因異常退出,編譯器不會(huì)刪除該指針,已分配的內(nèi)存將不會(huì)釋放。
在查找匹配的catch期間,不是尋找最佳匹配,而是選中第一個(gè)找到的可以處理該異常的cahtch
如果被拋出的對(duì)象是派生類類型的,但由接受基類類型的catch處理,cahtch將不能使用派生類特有的所有成員,所以cahtch子句處理因繼承而相關(guān)的類型的異常,它就應(yīng)該將自己的形參定義為引用。
重新拋出throw,當(dāng)catch無法處理的時(shí)候,將重新拋出throw將異常傳遞給函數(shù)調(diào)用鏈中更上層的函數(shù)
exception類所地被你故意的唯一操作時(shí)一個(gè)名為what的虛成員,該函數(shù)返回,const char*
可能存在異常的程序以及分配資源的程序應(yīng)該使用類來管理那些資源,如果函數(shù)因異常而提早退出,編譯器就運(yùn)行類的析構(gòu)函數(shù)最為異常處理過程的一部分。
77auto_ptr
為異常安全的內(nèi)存分配使用auto_ptr,
當(dāng)復(fù)制auto_ptr對(duì)象或者將它的值付給其他arto_por對(duì)象的時(shí)候,將基礎(chǔ)對(duì)象的所有權(quán)從原來的auto_ptr對(duì)象傳給副本,原來的auto_ptr對(duì)象重置為未綁定狀態(tài)
賦值操作刪除做操作數(shù)指向的對(duì)象
應(yīng)該只用get詢問auto_ptr對(duì)象或者使用返回的指針值,不能用get作為創(chuàng)建其他auto_ptr的實(shí)參
調(diào)用auto_ptr的reset的時(shí)候,會(huì)刪除auto_ptr所指向的對(duì)象。
不要使用兩個(gè)auto_ptr指向同一對(duì)象,不要使用auto保存對(duì)象保存指向動(dòng)態(tài)分配數(shù)組的指針,以為當(dāng)auto_ptr被刪除的時(shí)候,它使用的是delete操作符,不是delete[]
78c++內(nèi)存分配方式
(1)allocator 類
(2)標(biāo)準(zhǔn)庫中的oprator new和operator delete函數(shù)
79new operator(primerl里面成為operator new 函數(shù)) operator new 和placement new
new operator :
(1)string *sp = new string("abc");
1.先調(diào)用operator new 的標(biāo)準(zhǔn)庫函數(shù)分配足夠大的原始的為類型化的內(nèi)存2.以保存指定內(nèi)存的一個(gè)對(duì)象;運(yùn)行該類型的一個(gè)構(gòu)造函數(shù),用指定初始化式構(gòu)造對(duì)象,3.返回指向新分配內(nèi)存并構(gòu)造的指針。
(2)operator new:
void *operator new(size_t)
void *operator new[](size_t)
獲得未構(gòu)造的內(nèi)存
operator detete不會(huì)調(diào)用析構(gòu)函數(shù),只會(huì)釋放指定內(nèi)存
(3)placement new:(定位new)
new (place_address)type
place_address為一個(gè)指針,
80運(yùn)行類型識(shí)別(RTTI)
(1)typeid操作符,返回指針或引用類型所致對(duì)象的實(shí)際類型
base *pb;
derived *pd;
if(typeid(*pb) == typeid(*pd))
{
//測(cè)試對(duì)象動(dòng)態(tài)類型
}
if(typeid(pb) == typed(pd))
{
//測(cè)試指針的靜態(tài)編譯的類型,永遠(yuǎn)不等
}
(2)dynamic_cast操作符,將基類類型的指針或引用安全轉(zhuǎn)化為派生類類型的指針或引用
dynamic_cast<*derived>(BasePtr)
81類成員函數(shù)指針和成員指針
類數(shù)據(jù)成員指針定義:
類型 類名::* name
成員函數(shù)指針定義
返回類型 (類名::指針名 *)(形參列表)
82volatile限定符
直接處理硬件的程序常具有這樣的數(shù)據(jù)成員,它們的值由程序本身直接控制之外的過程所控制。例如,程序可以包含由系統(tǒng)時(shí)鐘更新的變量。當(dāng)可以用編譯器的控制或檢測(cè)之外的方式改變對(duì)象值的時(shí)候,應(yīng)該將對(duì)象聲明為 volatile。關(guān)鍵字 volatile 是給編譯器的指示,指出對(duì)這樣的對(duì)象不應(yīng)該執(zhí)行優(yōu)化。 |