1. 程式人生 > >C++知識點:拷貝構造函數例子

C++知識點:拷貝構造函數例子

inside 現在 pan 創建 需要 string esp 傳遞對象 知識

//拷貝構造函數:
//函數參數傳遞時調用一次拷貝構造函數,給對象賦值時調用一次拷貝構造函數,對象作為參數傳遞後會被及時銷毀。
#include <fstream>
#include <string>
using namespace std;
ofstream out("HowMany2.out");

class HowMany2
{
    string name;//object identifier
    static int objectCount;
public:
    HowMany2(const string& id = "") : name(id)
    {
        
++objectCount; print("HowMany2()"); } ~HowMany2() { --objectCount; print("~HowMany2()"); } // the copy-constructor; HowMany2(const HowMany2& h) : name(h.name) { name += " copy"; ++objectCount; print("HowMany2(const HowMany2&)
"); } void print(const string& msg = "") const { if (msg.size() != 0) { out << msg << endl; } out << \t << name << ":" << "objectcount=" << objectCount << endl; } }; int HowMany2::objectCount = 0
; //pass and return By value: HowMany2 f(HowMany2 x) { x.print("x argument inside f()"); out << "Returning from f()" << endl; return x; } int main() { HowMany2 h("h"); //1.HowMany2() //2.h:objectCount = 1 out << "Entering f()" << endl; //3.Entering f() /*進入f(h) 此時拷貝構造函數被編譯器調用,完成傳值過程, 在f()內創建了一個新對象,他是h的拷貝,所以對象變成2 輸出: //傳遞對象作為函數參數時即發生拷貝構造 4.HowMany2(const HowMany2&) 5.h copy :objectcount=2 6.x argument inside f() 7.h copy:objectcount=3 8.returning from f() 第8顯示了從f()返回的開始情況,但在局部變量“h拷貝”銷毀前 (在函數結尾這個局部變量出了範圍)他必須被拷入返回值,也就是h2. 以前未創建的對象h2是從現在的對象(在函數f()內的局部變量創建的) 所以在第9行拷貝構造函數又被調用了。 現在對於h2的標識符,名字變成了h拷貝的拷貝,因為他是從拷貝拷過來的, 這個拷貝是函數f()內部對象, 在對象返回之後,函數結束之前,對象數暫時變為3,但是此後h拷貝被銷毀。 */ HowMany2 h2 = f(h); //在完成對f()的調用後,僅有兩個對象h和h2,這是看到h2最終是h拷貝的拷貝 h2.print("h2 after call to f()"); out << "call f() , no return value" << endl; //從第15行開始調用f(h),這次調用忽略了返回值,在16行可以看到恰好在參數傳入之前, //拷貝構造函數被調用。和前面一樣,21行顯示了為了返回值而調用拷貝構造函數。但是拷貝構造函數必修 //有一個作為它的目的地址(this指針)的工作地址,但這個地址從哪裏來呢? //每當編譯器為了正確地計算一個看不見的對象而需要一個臨時對象時,編譯器都會創建一個,在這種情況下 //編譯器創建一個看不見的對象作為函數f()忽略了的返回值的目標地址。這個臨時對象的生存期應該盡可能的短暫, //這樣空間就不會被這些等待被銷毀的而且占用資源的臨時對象搞亂。在一些情況下,臨時對象可能立刻被傳遞給 //另外的函數,但是現在這種情況下臨時對象不再需要,所以一旦調用完畢就對內部對象調用析構函數(23-24) //這個臨時對象被銷毀(25-26) //28-31行,h2,h被銷毀 f(h); out << "After call to f()" << endl; } //輸出結果: /* 1.HowMany2() 2.h:objectCount=1 3.Entering f() //傳遞對象作為函數參數時即發生拷貝構造 4.HowMany2(const HowMany2&) 5.h copy :objectcount=2 -------------------------- 6.x argument inside f() 7.h copy:objectcount=3 8.returning from f() //返回對象再次調用拷貝構造函數 -------------------------- 9.HowMany2(const HowMany2&) 10.h copy copy: objectCount=3 //臨時對象使用完畢,析構 11.~HowMany2() 12.h copy : objectcount=2 13.h2 after call to f() 14.h copy copy: objectCount=2 15.call f(),no return value //f(h) 16.HowMany2(const HowMany2&) 17.h copy: objectcount=3 18.x argument inside f() 19.h copy:objectCount=3 20.Returning from f() //f(h)後賦值給未知的值,在此調用拷貝構造函數 21.HowMany2(const HowMany2&) 22.h copy copy:objectCount = 4 //臨時對象使用完畢再次調用析構函數 23.~HowMany2() 24.h copy : objectCount = 3 //銷毀匿名的對象 25.~HowMany2() 26.h copy copy:objectCount=2 27.After call to f() 28.~HowMany2() 29.h copy copy :objectcount=1 30.~HowMany2() 31.h: objectcount=0 */

C++知識點:拷貝構造函數例子