程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++結構函數深度進修

C++結構函數深度進修

編輯:關於C++

C++結構函數深度進修。本站提示廣大學習愛好者:(C++結構函數深度進修)文章只能為提供參考,不一定能成為您想要的結果。以下是C++結構函數深度進修正文


本文針對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及以上的版本應用,這個辦法局限性很年夜,不外確切很便利。

以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved