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

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

C++構造函數深度學習

2020-05-23 14:01:03
字體:
來源:轉載
供稿:網友

本文針對C++構造函數進行深度探究,供大家參考,具體內容如下

1、引子: 
以下代碼中的輸出語句輸出0嗎,為什么?

struct Test{  int _a;  Test(int a) : _a(a) {}  Test()  {    Test(0);  }};Test obj;cout << obj._a << endl; 

輸出為:-858993460

2、剖析
上面代碼的輸出為一個垃圾值,也就是說obj調用構造函數并沒有對成員進行初始化工作,雖然默認無參構造Test()內部調用了Test(int a),但從結果看,初始化工作并不成功。這是為什么呢? 

在執行構造函數時,Test()并不會調用"this"對象(即obj對象)的Test::Test(int a),而是會用Test::Test(int a)來創建一個新的臨時實例對象,然后當這條語句執行完后,這個新的臨時對象馬上就會被銷毀。這樣一來,"this"對象就沒有被初始化,成員_a就是垃圾值,以后使用"this"對象就有可能產生一些問題。

3.重點:構造函數互相調用
 分析完這個題目之后,我們會想到另一個問題。也是我們今天重點關注的問題:

class Test{   int _a;   int _b;   int _c; public:  Test(int a, int b) : _a(a), _b(b),_c(0) {}   Test(int a, int b, int c); }; 

如果我們C++類中有兩個構造函數,分別為Test(int a, int b)和Test(int a, int b, int c)。如果我們的構造函數Test(int a, int b, int c)要完成所有成員(a,b,c)的賦值初始化工作,可以這樣寫:

Test::Test(int a, int b, int c)    : _a(a)  , _b(b)  , _c(c){ } 

但是,這樣寫又重復了構造函數Test(int a, int b)的工作,類成員少的情況下還好,如果成員非常多,重復寫的話代碼量過大,而且代碼可讀性降低了。然而我們可以看到構造函數Test(int a, int b)已經完成了成員a和成員b的賦值初始化工作,為了減少代碼量,就想著讓3個參數的構造函數調用2個參數的構造函數,然后在執行一些自己的代碼,這就如同派生類先調用基類的同名函數,再執行自己特有的代碼。但是這種機制如何實現呢? 

之前我們得出過結論:構造函數調用另一個構造函數并不能完成當前對象的初始化工作,只是初始化了臨時對象。下面我們就進入本文的核心問題:如何在構造函數中調用本類的另一個構造函數來初始化當前對象?

方法一:使用placement new技術,在3個參數中顯式調用2個參數的構造函數。
3參數構造函數可以這樣實現:

Test::Test(int a, int b, int c)  {   new (this) Test(a, b);   ... } 

構造函數分為2個執行階段:一是在初始化列表的初始化階段,二是在構造函數體內的賦值階段。上述方法是在第二個階段調用2個參數的構造函數。 

placement new是operator new的一個重載版本,只是我們很少用到它。如果你想在已經分配的內存中創建一個對象,使用new是不行的。也就是說placement new允許你在一個已經分配好的內存中(棧或堆中)構造一個新的對象。原型中void*p實際上就是指向一個已經分配好的內存緩沖區的的首地址。placement new技術的形式是 new(void *p) Type(...),表示在p所指的內存區域調用Type構造函數,該過程沒有內存請求。 

這個方法本質就是在對象地址處,調用2個參數的構造函數重新生成一個新的對象然后覆蓋該對象。這個實現方法有投機取巧的嫌疑。 

方法二:使用C++11新特性——委托構造函數(Delegating constructors)??梢栽跇嬙旌瘮党跏蓟斜碇苯诱{用,類似于調用基類構造函數。

Test::Test(int a, int b, int c) : Test(a, b) {   ... } 

上述說了構造函數有2個執行階段,該方法是在第一個階段進行的,更加方便。但是注意不能在Test(a, b)后面在接_c(c)了,因為調用2個參數的構造函數之后,就相當于該對象已經初始化完成了,不能在初始化列表放入其他成員的初始化形式。只能放在構造函數體中的賦值階段。該方法目前只能用在VS2013中。 

這個方法利用了C++11標準中的新特性——委托構造函數(Delegating constructors)。目前只能再VS2013及以上的版本使用,這個方法局限性很大,不過確實很方便。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 屯留县| 德安县| 沙雅县| 石林| 西吉县| 岐山县| 滨海县| 陵川县| 临海市| 泰州市| 定襄县| 伊春市| 蚌埠市| 宜章县| 噶尔县| 板桥市| 教育| 周至县| 新龙县| 洛宁县| 锦州市| 麻栗坡县| 和平县| 武穴市| 锡林浩特市| 拉孜县| 阳城县| 方城县| 浪卡子县| 微山县| 祥云县| 抚顺县| 定远县| 鄂伦春自治旗| 宜川县| 遂川县| 于田县| 冀州市| 南昌县| 灵山县| 荃湾区|