作者: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的預設建構函式),所以在函數體中的賦值是完全沒有意義的。
總之,建議使用初始化列表(注意是按照成員聲明順序,而不是列表順序)來做對象建立時初始化工作。
初始化順序為:
- 基類
- 成員資料成員(初始化列表)
- 建構函式函數體
附:練習
#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/