【C++學習】類初始化列表的分析總結

來源:互聯網
上載者:User

作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/

1.在子類構造時完成父類(沒有預設建構函式)的初始化參數傳入:

#include <iostream>
class Foo
{
        public:
        Foo( int x ) 
        {
                std::cout << "Foo's constructor " 
                          << "called with " 
                          << x 
                          << std::endl; 
        }
};
class Bar : public Foo
{
        public:
        Bar() : Foo( 10 )  // construct the Foo part of Bar
        { 
                std::cout << "Bar's constructor" << std::endl; 
        }
};
int main()
{
        Bar stool;
}

2.初始化const成員和reference成員

#include <iostream>
using namespace std;
class const_field
{
        public:
                const_field(int ii) : _constant( 1 ),ref( i ) { i=ii; }
                int geti(){return i;}
                int getref(){return ref;}
        private:
                const int _constant;
                int &ref;
                int i;
};
int main()
{
        const_field cos(100);
        cout << cos.geti() <<" " << cos.getref()<<endl;
}

 

註:初始化列表在建構函式函數體運行之前完成,在建構函式函數體運行中,資料成員的設定是賦值,而不是初始化。初始化階段可以是顯式或隱式的,這要取決於類成員的類型,對於built-in成員其實都一樣,但是對於類成員,是否存在成員初始化表則有所不同:若不存在則是隱式初始化,按照聲明的順序依次調用所有類成員函數所屬基類的預設建構函式(見後邊的練習),在函數體內有賦值動作調用賦值建構函式。若存在則屬於顯式初始化,類成員使用複製建構函式完成初始化,這也就是我們有時會說在初始化列表中初始化開銷會小些的原因(因為若在函數體內再賦值,那麼類成員函數的預設建構函式執行所做的工作都是無用功),例如:

Account(){

   _name = “”:

   _balance=0.0;

}

這裡面的string型的_name在賦值前已經被初始化階段隱式初始為空白串(調用了string的預設建構函式),所以在函數體中的賦值是完全沒有意義的。

總之,建議使用初始化列表(注意是按照成員聲明順序,而不是列表順序)來做對象建立時初始化工作。

初始化順序為:

  1. 基類
  2. 成員資料成員(初始化列表)
  3. 建構函式函數體

附:練習

#include <iostream>
using namespace std;
class Test
{
public:
 Test()
 {
  ctor_count++;
  cout<<"ctor "<<ctor_count<<endl;
 }
 Test(const Test & r)
 {
  ctor_count++;
  cout<<"copy ctor "<<ctor_count<<endl;
 }
 Test & operator= (const Test& r)
 {
  ctor_count++;
  cout<<"assignment op "<<ctor_count<<endl;
  return *this;
 }
private:
 static int ctor_count; //only a declaration
};
int Test::ctor_count=0; // definition + initialization
class Task
{
private:
 int pid;
 Test name; // type changed from string to Test
public:
 Task (int num, const Test & n) {pid=num; name=n;}
};
int main(void)
{
 Test t;
 Task task(1, t);
 return 0;
}

運行結果:

[root@localhost ~]# ./a.out
ctor 1
ctor 2
assignment op 3

解釋:static int是為了更好的說明問題,不要被這個類型所迷惑。第一行表示程式在構造t。第二行表示預設初始化時調用預設建構函式,第三行是構造task時的賦值。

將程式的初始化修改:

Task (int num, const Test & n):pid(num),name(n) {}

運行結果是:

ctor 1

copy ctor 2

下邊的這個程式也可以說明問題,如果還不理解上例的話:

#include <iostream>
using namespace std;
class Bar
{
public:
  Bar();
  Bar(int x);
  Bar & operator=(const Bar& bar)
  {
      cout <<"Assignment Bar constructed." <<endl;
  }
  Bar(const Bar &bar)
  {
      cout <<"Copy Bar constructed." <<endl;
  }
private:
  int x;
};
Bar::Bar()
{
  std::cout << "Bar default-constructed." << std::endl;
}
Bar::Bar(int x) : x(x)
{
  std::cout << "Bar constructed." << std::endl;
}
class Foo
{
public:
  Foo(Bar bar);
private:
  Bar bar;
};
Foo::Foo(Bar bar)
{
  this->bar = bar;
}
//Foo::Foo(Bar bar):bar(bar){}
int main()
{
    Foo foo(Bar(3));
    return 0;
}

作者:gnuhpc

出處:http://www.cnblogs.com/gnuhpc/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.