国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

Boolan C++ 學習2 Class with Pointer member

2019-11-11 03:08:53
字體:
來源:轉載
供稿:網友

Boolan C++ 學習2 Class with Pointer member

記錄知識點:

BigThree空指針const static sizeof explicit關鍵字new delete 內存分布C++ 數組指針類/函數模板Pointer/Function like objectC++ 11 待補充知識點

BigThree

拷貝構造, 復制構造, 析構函數 注意深淺拷貝: 如果你拷貝的對象中引用了某個外部的內容(比如分配在堆上的數據),那么在拷貝這個對象的時候,讓新舊兩個對象指向同一個外部的內容,就是淺拷貝;如果在拷貝這個對象的時候為新對象制作了外部對象的獨立拷貝,就是深拷貝 。 參考 http://blog.chinaunix.net/uid-24981687-id-3038952.html

空指針

早在 1972 年,C語言誕生的初期,常數 0 帶有常數及空指針的雙重身分。 C 使用 PReprocessor macro NULL 表示空指針, 讓 NULL 及 0 分別代表空指針及常數 0。 NULL 可被定義為 ((void*)0) 或是 0。 C++ 并不采用 C 的規則,不允許將 void* 隱式轉換為其他類型的指針。 為了使代碼 char* c = NULL; 能通過編譯,NULL 只能定義為 0。 這樣的決定使得函數重載無法區分代碼的語義: void foo(char *); void foo(int); C++ 建議 NULL 應當定義為 0,所以foo(NULL); 將會調用 foo(int), 這并不是程序員想要的行為,也違反了代碼的直觀性。0 的歧義在此處造成困擾。 C++11 引入了新的關鍵字來代表空指針常數:nullptr,將空指針和整數 0 的概念拆開。 nullptr 的類型為nullptr_t,能隱式轉換為任何指針或是成員指針的類型,也能和它們進行相等或不等的比較。 而nullptr不能隱式轉換為整數,也不能和整數做比較。 為了向下兼容,0 仍可代表空指針常數。 char* pc = nullptr; // OK int * pi = nullptr; // OK int i = nullptr; // error

foo(pc); // 呼叫 foo(char *) 參考https://zhidao.baidu.com/question/239782243804514164.htm

const static volatile sizeof explicit關鍵字

const 關鍵字 this指針如果在非const成員函數中,this指針只是一個類類型的;如果在const成員函數中,this指針是一個const類類型的;如果在volatile成員函數中,this指針就是一個volatile類類型的。 class A { …… void f(int i) {……} //一個函數 void f(int i) const {……} //上一個函數的重載 …… }; 上面是重載是沒有問題的了,那么下面的呢? class A { …… void f(int i) {……} //一個函數 void f(const int i) {……} //?? }; 這個是錯誤的,編譯通不過。那么是不是說明內部參數的const不予重載呢?再看下面的例子: class A { …… void f(int& ) {……} //一個函數 void f(const int& ) {……} //????? }; 這個程序是正確的,看來上面的結論是錯誤的。 關于const 重載幾乎在所有c++的書中者提到過但大部分只是一句話,例如在《C++ primer》一書中這樣描述:“可基于函數的引用形參是指向 const 對象還是指向非 const 對象,實現函數重載。將引用形參定義為 const 來重載函數是合法的,因為編譯器可以根據實參是否為 const 確定調用哪一個函數。” 但是這一段描述并沒有給出引用、指針和值傳遞前加const的實質區別是什么。在用非const的指針,引用和值均可轉化為const的。這一點沒有太多可說明的東東。

對于函數值傳遞的情況,因為參數傳遞是通過復制實參創建一個臨時變量傳遞進函數的,函數內只能改變臨時變量,但無法改變實參。則這個時候無論加不加const對實參不會產生任何影響。但是在引用或指針傳遞函數調用中,因為傳進去的是一個引用或指針,這樣函數內部可以改變引用或指針所指向的變量,這時const 才是實實在在地保護了實參所指向的變量。因為在編譯階段編譯器對調用函數的選擇是根據實參進行的,所以,只有引用傳遞和指針傳遞可以用是否加const來重載。 臨時變量都是const的所以傳值加const并不能使編譯器判斷重載。 類內部的常量限制:使用這種類內部的初始化語法的時候,常量必須是被一個常量表達式

初始化的整型或枚舉類型,而且必須是static和const形式。

· 如何初始化類內部的常量:一種方法就是static 和 const 并用,在外部初始化,例如:

class A { public: A() {} private: static const int i; file://注意必須是靜態的! };

const int A::i=3;另一個很常見的方法就是初始化列表: class A { public: A(int

i=0):test(i) {} private: const int i; }; 還有一種方式就是在外部初始化,

· 如果在非const成員函數中,this指針只是一個類類型的;如果在const成員函數中,

this指針是一個const類類型的;如果在volatile成員函數中,this指針就是一個

volatile類類型的。

· new返回的指針必須是const類型的。 參考http://blog.csdn.net/net_assassin/article/details/9997257 http://blog.chinaunix.net/uid-20443320-id-1945980.html 2. Static 關鍵字 1) 靜態全局變量 在全局變量前,加上關鍵字static,該變量就被定義成為一個靜態全局變量。 ? 該變量在全局數據區分配內存; ? 未經初始化的靜態全局變量會被程序自動初始化為0(自動變量的值是隨機的,除非它被顯式初始化); ? 靜態全局變量在聲明它的整個文件都是可見的,而在文件之外是不可見的;  靜態變量都在全局數據區分配內存,包括后面將要提到的靜態局部變量。對于一個完整的程序,在內存中的分布情況如下圖:  代碼區 全局數據區 堆區 棧區 一般程序的由new產生的動態數據存放在堆區,函數內部的自動變量存放在棧區。自動變量一般會隨著函數的退出而釋放空間,靜態數據(即使是函數內部的靜態局部變量)也存放在全局數據區。全局數據區的數據并不會因為函數的退出而釋放空間。細心的讀者可能會發現,Example 1中的代碼中將 “static int n; //定義靜態全局變量”改為“int n; //定義全局變量”。程序照樣正常運行。的確,定義全局變量就可以實現變量在文件中的共享,但定義靜態全局變量還有以下好處: ? 靜態全局變量不能被其它文件所用; ? 其它文件中可以定義相同名字的變量,不會發生沖突; static 可以表示內部。 2) 靜態局部變量 通常,在函數體內定義了一個變量,每當程序運行到該語句時都會給該局部變量分配棧內存。但隨著程序退出函數體,系統就會收回棧內存,局部變量也相應失效。但有時候我們需要在兩次調用之間對變量的值進行保存。通常的想法是定義一個全局變量來實現。但這樣一來,變量已經不再屬于函數本身了,不再僅受函數的控制,給程序的維護帶來不便。 靜態局部變量正好可以解決這個問題。靜態局部變量保存在全局數據區,而不是保存在棧中,每次的值保持到下一次調用,直到下次賦新值。 靜態局部變量有以下特點: ? 該變量在全局數據區分配內存; ? 靜態局部變量在程序執行到該對象的聲明處時被首次初始化,即以后的函數調用不再進行初始化; ? 靜態局部變量一般在聲明處初始化,如果沒有顯式初始化,會被程序自動初始化為0; ? 它始終駐留在全局數據區,直到程序運行結束。但其作用域為局部作用域,當定義它的函數或語句塊結束時,其作用域隨之結束; 3) 靜態函數 在函數的返回類型前加上static關鍵字,函數即被定義為靜態函數。靜態函數與普通函數不同,它只能在聲明它的文件當中可見,不能被其它文件使用。 ? 靜態函數不能被其它文件所用; ? 其它文件中可以定義相同名字的函數,不會發生沖突; 4)靜態數據成員 在類內數據成員的聲明前加上關鍵字static,該數據成員就是類內的靜態數據成員。 ? 對于非靜態數據成員,每個類對象都有自己的拷貝。而靜態數據成員被當作是類的成員。無論這個類的對象被定義了多少個,靜態數據成員在程序中也只有一份拷貝,由該類型的所有對象共享訪問。也就是說,靜態數據成員是該類的所有對象所共有的。對該類的多個對象來說,靜態數據成員只分配一次內存,供所有對象共用。所以,靜態數據成員的值對每個對象都是一樣的,它的值可以更新; ? 靜態數據成員存儲在全局數據區。靜態數據成員定義時要分配空間,所以不能在類聲明中定義。在Example 5中,語句int Myclass::Sum=0;是定義靜態數據成員; ? 靜態數據成員和普通數據成員一樣遵從public,protected,private訪問規則; ? 因為靜態數據成員在全局數據區分配內存,屬于本類的所有對象共享,所以,它不屬于特定的類對象,在沒有產生類對象時其作用域就可見,即在沒有產生類的實例時,我們就可以操作它; ? 靜態數據成員初始化與一般數據成員初始化不同。靜態數據成員初始化的格式為: <數據類型><類名>::<靜態數據成員名>=<值> ? 類的靜態數據成員有兩種訪問形式: <類對象名>.<靜態數據成員名> 或 <類類型名>::<靜態數據成員名> 如果靜態數據成員的訪問權限允許的話(即public的成員),可在程序中,按上述格式來引用靜態數據成員 ; ? 靜態數據成員主要用在各個對象都有相同的某項屬性的時候。比如對于一個存款類,每個實例的利息都是相同的。所以,應該把利息設為存款類的靜態數據成員。這有兩個好處,第一,不管定義多少個存款類對象,利息數據成員都共享分配在全局數據區的內存,所以節省存儲空間。第二,一旦利息需要改變時,只要改變一次,則所有存款類對象的利息全改變過來了; ? 同全局變量相比,使用靜態數據成員有兩個優勢: 1. 靜態數據成員沒有進入程序的全局名字空間,因此不存在與程序中其它全局名字沖突的可能性; 2. 可以實現信息隱藏。靜態數據成員可以是private成員,而全局變量不能; 5)靜態成員函數 與靜態數據成員一樣,我們也可以創建一個靜態成員函數,它為類的全部服務而不是為某一個類的具體對象服務。靜態成員函數與靜態數據成員一樣,都是類的內部實現,屬于類定義的一部分。普通的成員函數一般都隱含了一個this指針,this指針指向類的對象本身,因為普通成員函數總是具體的屬于某個類的具體對象的。通常情況下,this是缺省的。如函數fn()實際上是this->fn()。但是與普通函數相比,靜態成員函數由于不是與任何的對象相聯系,因此它不具有this指針。從這個意義上講,它無法訪問屬于類對象的非靜態數據成員,也無法訪問非靜態成員函數,它只能調用其余的靜態成員函數。 ? 出現在類體外的函數定義不能指定關鍵字static; ? 靜態成員之間可以相互訪問,包括靜態成員函數訪問靜態數據成員和訪問靜態成員函數; ? 非靜態成員函數可以任意地訪問靜態成員函數和靜態數據成員; ? 靜態成員函數不能訪問非靜態成員函數和非靜態數據成員; ? 由于沒有this指針的額外開銷,因此靜態成員函數與類的全局函數相比速度上會有少許的增長; ? 調用靜態成員函數,可以用成員訪問操作符(.)和(->)為一個類的對象或指向類對象的指針調用靜態成員函數,也可以直接使用如下格式: <類名>::<靜態成員函數名>(<參數表>) 調用類的靜態成員函數。 靜態成員函數由于沒有this指針所以不能定義const函數。 class::static func() const {} // error C++編譯器在實現const的成員函數的時候為了確保該函數不能修改類的實例的狀態,會在函數中添加一個隱式的參數const this*。但當一個成員為static的時候,該函數是沒有this指針的。也就是說此時const的用法和static是沖突的。 參考:http://www.cnblogs.com/BeyondAnyTime/archive/2012/06/08/2542315.html http://blog.csdn.net/bxyill/article/details/8444391 3. volatile 關鍵字 C/C++ 中的 volatile 關鍵字和 const 對應,用來修飾變量,通常用于建立語言級別的 memory barrier。這是 BS 在 “The C++ Programming Language” 對 volatile 修飾詞的說明:

A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.

volatile 關鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素更改,比如:操作系統、硬件或者其它線程等。遇到這個關鍵字聲明的變量,編譯器對訪問該變量的代碼就不再進行優化,從而可以提供對特殊地址的穩定訪問。聲明時語法:int volatile vInt; 當要求使用 volatile 聲明的變量的值的時候,系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過數據。而且讀取的數據立刻被保存。例如:

1 volatile int i=10; 2 int a = i; 3 … 4 // 其他代碼,并未明確告訴編譯器,對 i 進行過操作 5 int b = i; volatile 指出 i 是隨時可能發生變化的,每次使用它的時候必須從 i的地址中讀取,因而編譯器生成的匯編代碼會重新從i的地址讀取數據放在 b 中。而優化做法是,由于編譯器發現兩次從 i讀數據的代碼之間的代碼沒有對 i 進行過操作,它會自動把上次讀的數據放在 b 中。而不是重新從 i 里面讀。這樣以來,如果 i是一個寄存器變量或者表示一個端口數據就容易出錯,所以說 volatile 可以保證對特殊地址的穩定訪問。注意,在 VC 6 中,一般調試模式沒有進行代碼優化,所以這個關鍵字的作用看不出來。

參考:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html 4. sizeof 運算符 (0)sizeof是運算符,不是函數;

(1)sizeof不能求得void類型的長度;

(2)sizeof能求得void類型的指針的長度;

(3)sizeof能求得靜態分配內存的數組的長度!

(4)sizeof不能求得動態分配的內存的大小!

(5)sizeof不能對不完整的數組求長度;

(6)當表達式作為sizeof的操作數時,它返回表達式的計算結果的類型大小,但是它不對表達式求值!

(7)sizeof可以對函數調用求大小,并且求得的大小等于返回類型的大小,但是不執行函數體!

(8)sizeof求得的結構體(及其對象)的大小并不等于各個數據成員對象的大小之和!

(9)sizeof不能用于求結構體的位域成員的大小,但是可以求得包含位域成員的結構體的大小! 指針變量的sizeof值與指針所指的對象沒有任何關系。

參考http://www.cnblogs.com/bigbigtree/p/3580585.html http://blog.csdn.net/candyliuxj/article/details/6307814 5. explicit關鍵字 C++提供關鍵字explicit,可以阻止不應該允許的經過轉換構造函數進行的隱式轉換發生.

聲明為explicit的構造函數不能在隱式轉換中使用.

C++中,一個參數的構造函數(或者除了第一個參數外其余參數都有默認值的多參構造函數),承擔了兩個角色.

1.是個構造器,2.是個默認且隱含的類型轉換操作符.

寫下如AAA = XXX,這樣的代碼,且恰好XXX的類型正好是AAA單參數構造的參數類型,這時候編譯器就自動調用這個構造器,創建一個AAA的對象.

使用explicit聲明構造函數,則可防止隱式轉換,避免上述情況的發生 。 參考:http://www.cnblogs.com/dwdxdy/archive/2012/07/17/2595479.html http://blog.csdn.net/chollima/article/details/3486230 http://www.jb51.net/article/52164.htm

new delete 內存分布

new 三步驟 complex *pc = new complx(1,2); 1) void * mem = Operator new(sizeof(complex))//分配空間 2) pc = static_cast<”complex>( mem) 3) pc-> complex::complex(1,2) //構造函數 delete 兩步先析構再釋放mem。 delete pc; string ::~string(pc); operator delete(ps); array new 要用array delete delete [] 會調用幾次析構函數。

C++ 數組指針  數組名不是指針但是可以用作指針。 (1)數組名的內涵在于其指代實體是一種數據結構,這種數據結構就是數組;

(2)數組名的外延在于其可以轉換為指向其指代實體的指針,而且是一個指針常量;

(3)指向數組的指針則是另外一種變量類型(在WIN32平臺下,長度為4),僅僅意味著數組的存放地址!

數組名可能失去其數據結構內涵

(1)數組名作為函數形參時,在函數體內,其失去了本身的內涵,僅僅只是一個指針;

(2)很遺憾,在失去其內涵的同時,它還失去了其常量特性,可以作自增、自減等操作,可以被修改。

所以,數組名作為函數形參時,其全面淪落為一個普通指針!它的貴族身份被剝奪,成了一個地地道道的只擁有4個字節的平民。 數組指針 int (*p)[4]; //p是指針,指向一維數組,每個一維數組有4個int元素 指針數組 int* q[4];///指針數組 q是數組,數組元素是指針,3個int指針 參考:http://www.cnblogs.com/wuzhenbo/archive/2012/05/29/2523777.html http://blog.csdn.net/kaiming2008/article/details/5617155/

類/函數模板

在進行模板的類型推導時,傳入參數如果是引用,會被當作非引用,即忽略掉引用部分。

對統一引用參數進行類型推導時,左值參數會獲得特殊處理。

按值傳遞的參數進行類型推導時,const或者volatile參數會被處理成非const或非volatile。 參考:http://blog.csdn.net/coolmeme/article/details/43986163 https://www.zhihu.com/question/24671324 http://blog.csdn.net/zhang810413/article/details/1948603

Pointer/Function like object

一個函數對象,即一個重載了括號操作符“()”的對象。當用該對象調用此操作符時,其表現形式如同普通函數調用一般,因此取名叫函數對象。舉個最簡單的例子: class FuncObjType { public: void operator() () { cout<<”Hello C++!”<

C++ 11 待補充知識點

待添加。。。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 葫芦岛市| 东兰县| 苍南县| 万全县| 秦安县| 娄烦县| 天气| 双流县| 东平县| 朝阳市| 宁蒗| 嵊州市| 屏东市| 罗山县| 灵丘县| 泗阳县| 台江县| 军事| 依兰县| 佛坪县| 吉木乃县| 东港市| 启东市| 广东省| 冷水江市| 化州市| 林口县| 比如县| 乐山市| 普宁市| 女性| 黄石市| 苏尼特右旗| 闽侯县| 宿松县| 沙田区| 蓬溪县| 和静县| 蕉岭县| 汽车| 龙井市|