《深入C++面向對象模型》之拷貝構造函數

        花了幾天時間,把《深入C++面向對象模型》看了一半的樣子。確實如BBS上的同學說的那樣,“帥呆了!”,絕對讓你停不下來的節奏。這本書是C++經典書單裏面的常客,《Effective C++》也是很多人推薦。說實話吧!我手頭有一本《Effective C++》,卻一直沒有看完,準確地說是我沒有在閱讀的過程中得到很多樂趣。不是黑《Effective C++》,只是這本書的寫作模式是條款式的。它的關注點在於“出什麼問題?”以及“如何避免?”,而不是爲什麼會這樣。相對來說,這本書還是比較偏工程應用,而《深入C++面向對象模型》卻常常在分析編譯器的一些細節,感覺更底層,更學術一些吧!

        言歸正傳了,記一點拷貝構造函數相關的筆記。拷貝函數名爲“拷貝”,卻並不一定是無腦的copy。“無腦copy”的學名叫“Bitwise Copy”,就是每個bit都一起拷貝的方法。當一下四種情況出現的時候,Bitwise Copy Constructor就行了。

       1、2、當class內含一個或則繼承一個存在copy constructor的類;
       3、當class聲明瞭一個或多個virtual functions時;
       4、當class派生自一個繼承串鏈,其中有一個或多個virtual base classes時。

        前兩中情況下,編譯器必須將member或base class的copy constructors調用操作安插到被合成的copy constructor中;第三種情況主要是要準確設置vptr指向的位置;第四種情況中,是因爲虛基類的存在導致virtual base class的位置需要確定,所以不能簡單拷貝。

        函數返回值的實現和拷貝構造函數的關係也是非常密切的,下面是cfront(第一個C++編譯器)的實現方法。原函數如下:

X bar()
{
	X xx;
	//處理 xx ...
	rerurn xx;
}
         轉換後的僞代碼:

//函數轉換
//以反映出copy constructor的應用
//C++僞代碼
void
bar(X& _result)
{
	X xx;
	//編譯器所產生的default constructor調用操作
	xx.X::X();
	
	//...處理xx
	
	//編譯器所產生的copy constructor調用操作
	_result.X::X(xx);
	
	return;
}
        然後編譯器必須轉換每一個bar()調用操作,以反映其新定義。X xx = bar();被轉化爲一下兩個語句:
//注意,不必施行default constructor
X xx;
bar(xx);
         一個顯而易見的問題是程序效率。臨時變量和_result之間的拷貝無疑會降低程序效率。編譯器的優化方法如下:
//編譯器層面的優化:
X bar()
{
 X xx;
 //...處理xx
 return xx;
}
//編譯器把其中的xx以_result取代:
void
bar(X &_result)
{
		//default constructor被調用
		//C++僞代碼
		_result.X::X();
		//...直接處理_result
		return;
}
          這種優化有時被稱爲Named Return Value(NRV),在對象比較大的情況下,應該是可以節省不少時間的。


發佈了49 篇原創文章 · 獲贊 11 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章