青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
數據加載中……

C++ Primer讀書筆記

前些日子開始看《C++ Primer》,順便做一些筆記,既有書上的,也有自己理解的。
因為剛學C++不久,筆下難免有謬誤之處,行文更是凌亂;
所幸不是用來顯配的東西,發在linuxsir只是為了方便自己閱讀記憶,以防只顧上網忘了正事。
書看了不到一半,所以大約才寫了一半,慢慢補充。
=========================================


==========================================
轉載務必注明原作者
neplusultra 2005.2.3
==========================================


const要注意的問題
  1、下面是一個幾乎所有人剛開始都會搞錯的問題:
已知:typedef char *cstring;
在以下聲明中,cstr的類型是什么?
extern const cstring cstr;

錯誤答案:const char *cstr;
正確答案:char *const cstr;

  錯誤在于將typedef當作宏擴展。const 修飾cstr的類型。cstr是一個指針,因此,這個定義聲明了cstr是一個指向字符的const指針。
  2、指針是const還是data為const?
辨別方法很簡單,如下:
代碼:
char *p="hello"; //non-const pointer, non-const data; const char *p="hello"; // non-const pointer, const data; char * const p="hello"; // const pointer , non-const data; const char * const p="hello"; // const pointer, const data;
  要注意的是,"hello"的類型是const char * ,按C++standard規則,char *p="hello" 是非法的(右式的const char* 不能轉換為左式的char *),違反了常量性。但是這種行為在C中實在太頻繁,因此C++standard對于這種初始化動作給予豁免。盡管如此,還是盡量避免這種用法。
  3、const初始化的一些問題
const 對象必須被初始化:
代碼:
const int *pi=new int; // 錯誤,沒有初始化 const int *pi=new int(100); //正確 const int *pci=new const int[100]; //編譯錯誤,無法初始化用new表達式創建的內置類型數組元素。

什么時候需要copy constructor,copy assignment operator,destructor
  注意,若class需要三者之一,那么它往往需要三者。
當class的copy constructor內分配有一塊指向hcap的內存,需要由destructor釋放,那么它也往往需要三者。

為什么需要protected 訪問級別
  有人認為,protected訪問級別允許派生類直接訪問基類成員,這破壞了封裝的概念,因此所有基類的實現細節都應該是private的;另外一些人認為,如果派生類不能直接訪問基類的成員,那么派生類的實現將無法有足夠的效率供用戶使用,如果沒有protected,類的設計者將被迫把基類成員設置為public。
  事實上,protected正是在高純度的封裝與效率之間做出的一個良好折衷方案。

為什么需要virtual member function又不能濫用virtual
  若基類設計者把本應設計成virtual的成員函數設計成非virtual,則繼承類將無法實現改寫(overridden),給繼承類的實現帶來不便;
  另一方面,一旦成員函數被設計成virtual,則該類的對象將額外增加虛擬指針(vptr)和虛擬表格(vtbl),所以倘若出于方便繼承類overridden的目的而使所有成員函數都為virtual,可能會影響效率,因為每個virtual成員函數都需付出動態分派的成本。而且virtual成員函數不能內聯(inline),我們知道,內聯發生在編譯時刻,而虛擬函數在運行時刻才處理。對于那些小巧而被頻繁調用、與類型無關的函數,顯然不應該被設置成virtual。

關于引用的一些注意點
  1、把函數參數聲明為數組的引用:當函數參數是一個數組類型的引用時,數組長度成為參數和實參類型的一部分,編譯器檢查數組實參的長度和與在函數參數類型中指定的長度是否匹配。
代碼:
//參數為10個int數組 void showarr(int (&arr)[10]); void func() { int i,j[2],k[10]; showarr(i); //錯誤!實參必須是10個int的數組 showarr(j); //錯誤!實參必須是10個int的數組 showarr(k); //正確! } //更靈活的實現,借助函數模板。下面是一個顯示數組內容的函數。 template <typename Type , int size> void printarr(const Type (& r_array)[size]) { for(int i=0;i<size;i++) std::cout<< r_array[i] <<' '; std::cout << std::endl; } void caller() { int ar[5]={1,2,5,3,4}; //數組可以任意大小。 printarr(ar); //正確!自動正確調用printarr() }
  2、
  3、

goto語句的一些要注意的地方
  1、label語句只能用作goto的目標,且label語句只能用冒號結束,且label語句后面不能緊接右花括號'}',如
代碼:
label8: }
  辦法是在冒號后面加一個空語句(一個';'即可),如
代碼:
label7: ;}
   2、goto語句不能向前跳過如下聲明語句:
代碼:
goto label6; int x=1; //錯誤,不能跳過該聲明! cout<<x<<endl; //使用x label6: //其他語句
但是,把int x=1; 改為int x; 則正確了。另外一種方法是:
代碼:
goto label6; { int x=1; //正確,使用了語句快 cout<<x<<endl; } label6: //其他語句
  3、goto語句可以向后(向程序開頭的方向)跳過聲明定義語句。
代碼:
begin: int i=22; cout<< i <<endl; goto begin; //非常蹩腳,但它是正確的

變量作用域
  1、花括號可以用來指明局部作用域。
  2、在for、if、switch、while語句的條件/循環條件中可以聲明變量,該變量僅在相應語句塊內有效。
  3、extern為聲明但不定義一個對象提供了一種方法;它類似于函數聲明,指明該對象會在其他地方被定義:或者在此文本的其他地方,或者在程序的其他文本文件中。例如extern int i; 表示在其他地方存在聲明 int i;
  extern 聲明不會引起內存分配,他可以在同一個文件或同一個程序中出現多次。因此在全局作用域中,以下語句是正確的:
代碼:
extern int c; int c=1; //沒錯 extern int c; //沒錯
  但是,extern聲明若指定了一個顯式初始值的全局對象,將被視為對該對象的定義,編譯器將為其分配存儲區;對該對象的后續定義將出錯。如下:
代碼:
extern int i=1; int i=2; //出錯!重復定義

auto_ptr若干注意點
  1、auto_ptr的主要目的是支持普通指針類型相同的語法,并為auto_ptr所指對象的釋放提供自動管理,而且auto_ptr的安全性幾乎不會帶來額外的代價(因為其操作支持都是內聯的)。定義形式有三種:
代碼:
auto_ptr<type_pointed_to>identifier(ptr_allocated_by_new); auto_ptr<type_pointed_to>identifier(auto_ptr_of_same_type); auto_ptr<type_pointed_to>identifier;
  2、所有權概念。auto_ptr_p1=auto_ptr_p2的后果是,auto_ptr_p2喪失了其原指向對象的所有權,并且auto_ptr_p2.get()==0。不要讓兩個auto_ptr對象擁有空閑存儲區內同一對象的所有權。注意以下兩種種初始化方式的區別:
代碼:
auto_ptr<string>auto_ptr_str1(auto_ptr_str2.get()); //注意!用str2指針初始化str1, 兩者同時擁有所有權,后果未定義。 auto_ptr<string>auto_ptr_str1(auto_ptr_str2.release());//OK!str2釋放了所有權。

  3、不能用一個指向“內存不是通過應用new表達式分配的”指針來初始化或者賦值auto_ptr。如果這樣做了,delete表達式會被應用在不是動態分配的指針上,這將導致未定義的程序行為。

C風格字符串結尾空字符問題

代碼:
char *str="hello world!"; //str末尾自動加上一個結尾空字符,但strlen不計該空字符。 char *str2=new char[strlen(str)+1] // +1用來存放結尾空字符。


定位new表達式
  頭文件:<new>
  形式:new (place_address) type-specifier
  該語句可以允許程序員將對象創建在已經分配好的內存中,允許程序員預分配大量的內存供以后通過這種形式的new表達式創建對象。其中place_address必須是一個指針。例如:
代碼:
char *buf=new char[sizeof(myclass-type)*16]; myclass-type *pb=new (buf) myclass-type; //使用預分配空間來創建對象 // ... delete [] buf; // 無須 delete pb。


名字空間namespace

  1、namespace的定義可以是不連續的(即namespace的定義是可以積累的),即,同一個namespace可以在不同的文件中定義,分散在不同文件中的同一個namespace中的內容彼此可見。這對生成一個庫很有幫助,可以使我們更容易將庫的源代碼組織成接口和實現部分。如:在頭文件(.h文件)的名字空間部分定義庫接口;在實現文件(如.c或.cpp文件)的名字空間部分定義庫實現。名字空間定義可積累的特性是“向用戶隱藏實現細節”必需的,它允許把不同的實現文件(如.c或.cpp文件)編譯鏈接到一個程序中,而不會有編譯錯誤和鏈接錯誤。
  2、全局名字空間成員,可以用“::member_name”的方式引用。當全局名字空間的成員被嵌套的局部域中聲明的名字隱藏時,就可以采用這種方法引用全局名字空間成員。
  3、名字空間成員可以被定義在名字空間之外。但是,只有包圍該成員聲明的名字空間(也就是該成員聲明所在的名字空間及其外圍名字空間)才可以包含它的定義。
  尤其要注意的是#include語句的次序。假定名字空間成員mynamespace::member_i的聲明在文件dec.h中,且#include "dec.h"語句置于全局名字空間,那么在include語句之后定義的其他名字空間內,mynamespace::member_i的聲明均可見。即,mynamespace::member_i可以在#include "dec.h"之后的任何地方任何名字空間內定義。
  4、未命名的名字空間。我們可以用未命名的名字空間聲明一個局部于某一文件的實體。未命名的名字空間可以namespace開頭,其后不需名字,而用一對花括號包含名字空間聲明塊。如:
代碼:
// 其他代碼略 namespace { void mesg() { cout<<"**********\n"; } } int main() { mesg(); //正確     //... return 0; }
  由于未命名名字空間的成員是程序實體,所以mesg()可以在程序整個執行期間被調用。但是,未命名名字空間成員只在特定的文件中可見,在構成程序的其他文件中是不可以見的。未命名名字空間的成員與被聲明為static的全局實體具有類似的特性。在C中,被聲明為static的全局實體在聲明它的文件之外是不可見的。

using關鍵字
  1、using聲明與using指示符:前者是聲明某名字空間內的一個成員,后者是使用整個名字空間。例如:
代碼:
using cpp_primer::matrix; // ok,using聲明 using namespace cpp_primer; //ok,using指示符
  2、 該using指示符語句可以加在程序文件的幾乎任何地方,包括文件開頭(#include語句之前)、函數內部。不過用using指定的名字空間作用域(生命周期)受using語句所在位置的生命周期約束。如,函數內部使用“using namespace myspacename;”則 myspacename僅在該函數內部可見。
  3、可以用using語句指定多個名字空間,使得多個名字空間同時可見。但這增加了名字污染的可能性,而且只有在使用各名字空間相同成員時由多個using指示符引起的二義性錯誤才能被檢測到,這將給程序的檢測、擴展、移植帶來很大的隱患。因此,因該盡量使用using聲明而不是濫用using指示符。

重載函數
  1、如果兩個函數的參數表中參數的個數或者類型不同,則認為這兩個函數是重載的。
  如果兩個函數的返回類型和參數表精確匹配,則第二個聲明被視為第一個的重復聲明,與參數名無關。如 void print(string& str)與void print(string&)是一樣的。
  如果兩個函數的參數表相同,但是返回類型不同,則第二個聲明被視為第一個的錯誤重復聲明,會標記為編譯錯誤。
  如果在兩個函數的參數表中,只有缺省實參不同,則第二個聲明被視為第一個的重復聲明。如int max(int *ia,int sz)與int max(int *, int=10)。
  參數名類型如果是由typedef提供的,并不算作新類型,而應該當作typedef的原類型。
  當參數類型是const或者volatile時,分兩種情況:對于實參按值傳遞時,const、volatile修飾符可以忽略;對于把const、volatile應用在指針或者引用參數指向的類型時,const、volatile修飾符對于重載函數的聲明是有作用的。例如:
代碼:
//OK,以下兩個聲明其實一樣 void func(int i); void func(const int i); //Error,無法通過編譯,因為func函數被定義了兩次。 void func(int i){} void func(const int i){} //OK,聲明了不同的函數 void func2(int *); void func2(const int *); //OK,聲明了不同的函數 void func3(int&); void func3(const int&);
  2、鏈接指示符extern "C"只能指定重載函數集中的一個函數。原因與內部名編碼有關,在大多數編譯器內部,每個函數明及其相關參數表都被作為一個惟一的內部名編碼,一般的做法是把參數的個數和類型都進行編碼,然后將其附在函數名后面。但是這種編碼不使用于用鏈接指示符extern "C"聲明的函數,這就是為什么在重載函數集合中只有一個函數可以被聲明為extern "C"的原因,具有不同的參數表的兩個extern "C"的函數會被鏈接編輯器視為同一函數。例如,包含以下兩個聲明的程序是非法的。
代碼:
//error:一個重載函數集中有兩個extern "C"函數 extern "C" void print(const char*); extern "C" void print(int);

函數模板
  1、定義函數模板:
代碼:
template <typename/class identifier, ...> [inline/extern] ReturnType FunctionName(FuncParameters...) {   //definition of a funciton template... }

posted on 2006-06-29 15:11 井泉 閱讀(295) 評論(1)  編輯 收藏 引用 所屬分類: C++

評論

# re: C++ Primer讀書筆記  回復  更多評論   

真認真呀
2010-03-09 16:09 | nfl 2010
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            91久久久亚洲精品| 欧美激情小视频| 亚洲欧美日韩国产一区二区| 在线精品视频一区二区| 国产热re99久久6国产精品| 欧美日本中文字幕| 欧美丝袜一区二区三区| 欧美日韩四区| 国产精品久久久久久久9999| 欧美视频一区| 国产精品美女主播在线观看纯欲| 欧美色精品天天在线观看视频 | 久久不射2019中文字幕| 欧美精品一卡二卡| 欧美日韩精品一区二区在线播放 | 亚洲美女视频在线免费观看| 亚洲国产裸拍裸体视频在线观看乱了| 久久久一区二区| 欧美成人黑人xx视频免费观看| 久久影院午夜片一区| 免费一级欧美片在线播放| 亚洲区在线播放| 亚洲免费在线视频| 你懂的一区二区| 国产噜噜噜噜噜久久久久久久久 | 欧美极品一区| 国产欧美日韩三区| 亚洲国产成人高清精品| 午夜精品在线| 亚洲人成免费| 久久久久久久网站| 国产精品入口日韩视频大尺度| 在线播放亚洲一区| 9l国产精品久久久久麻豆| 亚洲欧美日韩视频二区| 麻豆乱码国产一区二区三区| 亚洲三级免费观看| 久久久久久久尹人综合网亚洲| 久热精品视频在线| 欧美日韩在线视频一区| 国产精品一区二区三区久久| 亚洲欧美清纯在线制服| 99日韩精品| 亚洲电影第1页| 国产在线不卡| 亚洲激情小视频| 在线观看不卡av| 91久久在线观看| 亚洲高清123| 亚洲精品在线电影| 亚洲精品黄色| 国产精品久久久免费| 中文有码久久| 亚洲精品在线三区| 亚洲精品一级| 亚洲精品视频免费在线观看| 亚洲黄色在线观看| 亚洲深夜福利| 久久久精品动漫| 香蕉久久夜色精品国产| 国产日韩精品一区二区浪潮av| 欧美成人自拍| 欧美日韩国产一区精品一区 | 欧美一站二站| 欧美成人免费网| 国产精品乱码一区二区三区| 曰本成人黄色| 亚洲国产精品久久久久| 亚洲人成网站999久久久综合| 日韩一区二区精品| 亚洲欧美怡红院| 欧美国产日本在线| 99成人免费视频| 久久精品毛片| 久久婷婷综合激情| 久久福利一区| 久久精品人人做人人爽电影蜜月| 国产喷白浆一区二区三区 | 欧美日韩福利在线观看| 国产一区二区三区在线观看视频| 亚洲黄色精品| 久久综合色天天久久综合图片| 日韩天堂在线视频| 欧美成人日本| 在线观看亚洲| 久久久999精品| 亚洲一区在线视频| 欧美三级电影大全| 亚洲人成人一区二区三区| 久久夜色精品国产亚洲aⅴ| 亚洲视频二区| 国产精品二区在线| 亚洲综合三区| 99xxxx成人网| 国产精品久久久久久久久免费| 一本大道久久a久久综合婷婷| 欧美成人免费在线观看| 久久男人资源视频| 亚洲成色www8888| 久久日韩精品| 久久亚洲高清| 欧美三级在线视频| 久久久人成影片一区二区三区 | 欧美高清视频免费观看| 欧美精品99| 欧美日韩在线亚洲一区蜜芽| 欧美午夜激情在线| 亚洲精品久久久久久久久久久久 | 久久亚洲国产精品日日av夜夜| 国内揄拍国内精品久久| 久久女同互慰一区二区三区| 久久黄色小说| 欧美日本一区二区视频在线观看| 91久久亚洲| 亚洲日本欧美| 欧美亚洲成人免费| 欧美一区二区三区在| 亚洲欧美日韩国产精品| 国产一级久久| 亚洲国产精品激情在线观看| 免费观看久久久4p| 亚洲精品一区二区网址| 日韩视频精品| 亚洲在线一区| 欧美日韩日韩| 99热这里只有精品8| 亚洲精品孕妇| 欧美精品一区二区三区在线播放| 91久久极品少妇xxxxⅹ软件| 男女视频一区二区| 久久久久国产一区二区| 亚洲激情一区二区三区| av成人免费在线| 国产精品青草久久| 免费成人毛片| 欧美日韩一区二| 亚洲免费一在线| 久久精品网址| 欧美国产激情| 亚洲高清在线观看一区| 玖玖综合伊人| 久久深夜福利| 日韩一级大片| 亚洲欧美伊人| 亚洲全部视频| 亚洲欧美日产图| 亚洲国产一成人久久精品| 性欧美xxxx大乳国产app| 亚洲午夜三级在线| 国产精品久久久久久久久久免费看| 久久综合九色九九| 国产精品一区二区三区四区五区| 午夜亚洲影视| 久久精品论坛| 一区二区三区欧美激情| 性伦欧美刺激片在线观看| 国产欧美亚洲日本| 国产色婷婷国产综合在线理论片a| 欧美在线一区二区| 牛夜精品久久久久久久99黑人| 亚洲婷婷综合久久一本伊一区| 亚洲午夜视频在线| 1024亚洲| 亚洲综合精品一区二区| 一区二区三区精品视频在线观看| 中文网丁香综合网| 亚洲精选视频免费看| 久久精品免费| 午夜激情久久久| 国产精品老牛| 亚洲老板91色精品久久| 欧美激情一区二区三区四区 | 亚洲视频在线视频| 亚洲人屁股眼子交8| 久久精品成人一区二区三区| 亚洲欧美网站| 欧美日韩18| 亚洲高清三级视频| 亚洲成人中文| 免费看的黄色欧美网站| 老司机精品导航| 国产精品一卡| 亚洲一区二区三区视频| 欧美亚洲一区二区三区| 欧美日韩大片| 亚洲免费激情| 亚洲一区免费观看| 欧美国产另类| 亚洲精品免费在线| 国产区精品在线观看| 亚洲国产精品精华液网站| 黄色一区三区| 欧美亚洲免费电影| 毛片一区二区三区| 亚洲精品欧美专区| 欧美成人免费观看| 亚洲自啪免费| 欧美一级片一区| 国内外成人在线视频| 老司机午夜精品视频|