下面來看一個例子:
class test
{
public:
test()
{
cout << "constructor with argument\n";
}
~test()
{
}
test(test& t)
{
cout << "copy constructor\n";
}
test&operator=(const test&e)
{
cout << "assignment operator\n";
return *this;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
test ort;
test a(ort);
test b = ort ;
a = b;
return 0;
}
輸出:
如果這些知識你都能理解。下面就來解釋一下為什么值傳遞會無限遞歸!
如果復制構造函數是這樣的 :
test(test t);
我們調用
test ort;
test a(ort); --> test.a(test t=ort)==test.a(test t(ort))
-->test.a(test t(test t = ort))
==test.a(test t(test t(ort)))
-->test.a(test t(test t(test t=ort)))
- ...
就這樣會一直無限遞歸下去。
到這里,我們也就明白了,為什么拷貝構造函數的參數一定要為引用,不能為值傳遞的原因了。
接下來,我們再測試一下賦值構造函數的參數,如果我們把它的參數也改為值傳遞,做一個測試。
class test
{
public:
test()
{
cout << "constructor with argument\n";
}
~test()
{
}
test(test& t)
{
cout << "copy constructor\n";
}
test&operator=(test e)
{
cout << "assignment operator\n";
return *this;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
test ort;
test a(ort);
test b = ort ;
a = b;
return 0;
}
輸出:
賦值構造函數如果為值傳遞,僅僅是多了一次拷貝,並不會無限遞歸。
總結:拷貝構造函數的參數必須為引用。賦值構造函數參數既可以為引用,也可以為值傳遞,值傳遞會多一次拷貝。因此建議賦值構造函數建議也寫為引用類型。(CKK看 剛才我的理解還是有偏差:左右值不是關鍵,減少拷貝次數提高賦值效率是重點)
