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

隨筆 - 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>
            中文亚洲视频在线| 欧美电影在线播放| 欧美在线www| 亚洲一区成人| 欧美日韩国产欧| 欧美日韩精品三区| 国产精品视频久久| 在线观看国产成人av片| 韩国av一区二区三区四区| 国产资源精品在线观看| 黄色成人小视频| 亚洲国产成人在线播放| 日韩一级成人av| 欧美在线视频一区二区| 免费久久99精品国产自| 亚洲黄色小视频| 亚洲国产精品视频| 亚洲免费视频一区二区| 久久久女女女女999久久| 欧美不卡高清| 国产日韩一区二区| 亚洲理论在线观看| 久久久久九九九| 亚洲麻豆国产自偷在线| 久久成人羞羞网站| 欧美日韩一区二区在线视频| 国产伦精品免费视频| 亚洲激情中文1区| 欧美一区二区在线免费观看| 欧美成人性生活| 亚洲欧美国产高清va在线播| 免费中文字幕日韩欧美| 国产精品久久网站| 亚洲高清资源综合久久精品| 午夜国产精品视频| 欧美激情视频在线播放| 欧美一级一区| 欧美视频在线一区二区三区| 亚洲大片免费看| 欧美一级欧美一级在线播放| 亚洲电影在线观看| 久久久久一区二区三区四区| 99国产精品私拍| 国产精品自拍在线| aⅴ色国产欧美| 欧美 日韩 国产在线| 亚洲专区国产精品| 欧美久久一区| 亚洲国语精品自产拍在线观看| 亚洲在线视频观看| 亚洲人成人99网站| 美女视频网站黄色亚洲| 国产亚洲欧洲| 亚洲欧美在线另类| 一本色道久久综合亚洲精品小说 | 欧美日韩成人免费| 最新精品在线| 你懂的国产精品永久在线| 香蕉免费一区二区三区在线观看 | 欧美成年人在线观看| 亚洲素人一区二区| 欧美视频免费在线观看| 亚洲国产日韩欧美| 亚洲成人在线视频播放 | 久久高清福利视频| 欧美色区777第一页| 亚洲免费观看高清完整版在线观看熊 | 欧美在线视频一区二区| 在线综合亚洲| 国产精品区一区| 欧美一区二区三区视频在线| 亚洲尤物视频在线| 国产精自产拍久久久久久| 午夜影院日韩| 久久精品一本| 亚洲精品一区二区三区四区高清| 亚洲激情二区| 欧美午夜一区二区福利视频| 午夜在线精品偷拍| 久久精品亚洲| 一区二区三区国产在线| 亚洲女ⅴideoshd黑人| 国产综合视频| 亚洲精品免费在线播放| 国产精品国产三级国产| 久久久人成影片一区二区三区观看| 久久久精品久久久久| 亚洲高清久久久| 日韩视频在线观看国产| 国产午夜一区二区三区| 久久青青草原一区二区| 欧美成年视频| 午夜激情久久久| 久久精品国产亚洲一区二区| 亚洲第一精品在线| 一区二区三区四区蜜桃| 国产最新精品精品你懂的| 亚洲黄色成人久久久| 国产精品美女一区二区| 欧美成人69av| 国产精品你懂得| 亚洲国产精品va在线观看黑人| 国产精品久久久免费| 欧美国产日韩精品| 国产视频观看一区| 日韩视频中文字幕| 伊人久久婷婷| 欧美四级在线观看| 国产精品一区二区久久| 亚洲国产精品久久久| 国产精品久久久久久久久久免费 | 亚洲第一精品影视| 国产欧美一区二区三区另类精品 | 国产一区二区久久| 一区二区精品国产| 亚洲区在线播放| 欧美亚洲综合网| 亚洲手机在线| 欧美精品久久久久久久久老牛影院 | 欧美理论电影在线观看| 性一交一乱一区二区洋洋av| 欧美精品videossex性护士| 久久这里有精品15一区二区三区| 国产精品卡一卡二| 亚洲乱码国产乱码精品精可以看 | 亚洲乱码久久| 久热国产精品视频| 久久婷婷亚洲| 国产亚洲成精品久久| 欧美激情一区二区三区不卡| 欧美午夜精品久久久久久久 | 亚洲人成在线观看网站高清| 国产精品欧美久久久久无广告| 亚洲国产精品精华液2区45| 国内精品久久久久久久97牛牛| 一本色道久久综合亚洲精品婷婷 | 亚洲视频在线观看免费| 这里只有视频精品| 欧美久久电影| 日韩五码在线| 亚洲午夜免费视频| 欧美日韩在线精品| 一区二区三区www| 亚洲一区二区在线免费观看视频| 欧美美女操人视频| 亚洲看片网站| 亚洲欧美电影院| 国产日本欧美视频| 欧美专区在线播放| 蜜桃久久精品乱码一区二区| 狠狠狠色丁香婷婷综合久久五月| 亚洲欧美日韩国产成人精品影院| 午夜精品在线看| 国产亚洲成精品久久| 久久九九电影| 亚洲精品免费网站| 欧美在线不卡视频| 伊人久久男人天堂| 欧美国产日产韩国视频| 亚洲精品欧美| 午夜精品久久久久久99热| 国产日本欧美在线观看| 久久亚洲精品网站| 亚洲激情电影在线| 久久精品国产2020观看福利| 国产偷久久久精品专区| 久久久精品日韩| 亚洲人成小说网站色在线| 欧美一区二视频| 欧美日韩高清区| 小处雏高清一区二区三区| 欧美大片免费| 欧美一级视频精品观看| 亚洲成人资源| 国产精品都在这里| 久久久久久亚洲精品中文字幕| 亚洲欧洲日产国产网站| 欧美一级电影久久| 亚洲人被黑人高潮完整版| 国产精品盗摄久久久| 久久夜色精品国产| 亚洲综合久久久久| 亚洲国产精品一区二区www在线 | 一区二区久久久久| 欧美成人午夜视频| 欧美一区二区三区在线看| 亚洲精品美女久久7777777| 国产精品久久久一区麻豆最新章节| 久久日韩精品| 西瓜成人精品人成网站| 亚洲精品资源美女情侣酒店| 欧美在线视频免费观看| 野花国产精品入口| 久久综合中文字幕| 亚洲精品久久| 久久只精品国产| 亚洲一区二区欧美日韩| 亚洲精美视频| 黄色小说综合网站| 国产午夜精品全部视频播放 |