對象在不同情況下的建構函式和解構函式的調用差異很大
建構函式和解構函式的調用次數有所不同
當對象做參數時,實參完全複製給形參,所以不需再調用建構函式
其實是調用的拷貝建構函式即CClass a();CClass b=a;
但形參運行時為臨時變數,需調用解構函式
但對象引用做參數時,因為是原實參本身,所以在函數內不會調用析構
#include <iostream><br />using namespace std;</p><p>class Aclass<br />{<br />public:<br />int a;<br />Aclass(int t=0){<br />this->a=t;<br />cout<<"constructor "<<a<<endl;<br />}<br />void print(){<br />cout<<"print "<<this->a<<endl;<br />}<br />~Aclass(){<br />cout<<"destructor "<<a<<endl;<br />}</p><p>};</p><p>Aclass test(Aclass para)//attention please!!!<br />{<br />Aclass tmp(4);<br />tmp.print();<br />tmp.a=para.a+1;<br />para.print();<br />return tmp;</p><p>}<br />void main()<br />{<br />Aclass t1(2);<br />Aclass t2;<br />t2=test(t1);<br />t1.print();<br />t2.print();</p><p>}<br />
結果是:
constructor 2
constructor 0
constructor 4
print 4
print 2
destructor 3
destructor 2
destructor 3
print 2
print 3
destructor 3
destructor 2
Press any key to continue
#include <iostream><br />using namespace std;</p><p>class Aclass<br />{<br />public:<br />int a;<br />Aclass(int t=0){<br />this->a=t;<br />cout<<"constructor "<<a<<endl;<br />}<br />void print(){<br />cout<<"print "<<this->a<<endl;<br />}<br />~Aclass(){<br />cout<<"destructor "<<a<<endl;<br />}</p><p>};</p><p>Aclass test(Aclass& para)//attention please!!!<br />{<br />Aclass tmp(4);<br />tmp.print();<br />tmp.a=para.a+1;<br />para.print();<br />return tmp;</p><p>}<br />void main()<br />{<br />Aclass t1(2);<br />Aclass t2;<br />t2=test(t1);<br />t1.print();<br />t2.print();</p><p>}<br />
結果是
constructor 2
constructor 0
constructor 4
print 4
print 2
destructor 3 (the parameter object's destruction has gone )
destructor 3
print 2
print 3
destructor 3
destructor 2
Press any key to continue
參數引用的實參解構函式沒了
多出來的解構函式是誰的呢
利用斷點調試的時候可以清晰的看出constructor對應的destructor
先看下例
#include <iostream><br />using namespace std;</p><p>class Aclass<br />{<br />public:<br />int a;<br />Aclass(int t=0){<br />this->a=t;<br />cout<<"constructor "<<a<<endl;<br />}<br />void print(){<br />cout<<"print "<<this->a<<endl;<br />}<br />~Aclass(){<br />cout<<"destructor "<<a<<endl;<br />}</p><p>};</p><p>void test(Aclass& para)<br />{<br />Aclass tmp(4);<br />tmp.a=para.a+1;<br />}<br />void main()<br />{<br />Aclass t1(2);<br />Aclass t2;<br />test(t1);<br />}
結果
constructor 2
constructor 0
constructor 4
destructor 3
destructor 0
destructor 2
Press any key to continue
數量一致
差別主要在return 語句
那麼,問題很可能就在這裡
我們有一種猜測,就是函數返回時,先對要返回的局部變數做一份拷貝,函數返回
之後 ,才把傳回值賦給被賦值變數
有待證明
#include <iostream><br />using namespace std;</p><p>class Aclass<br />{<br />public:<br />int a;<br />Aclass(int t=0){<br />this->a=t;<br />cout<<"constructor "<<a<<endl;<br />}<br />void print(){<br />cout<<"print "<<this->a<<endl;<br />}<br />~Aclass(){<br />cout<<"destructor "<<a<<endl;<br />}</p><p>};</p><p>Aclass* test(Aclass para)<br />{<br />Aclass tmp(4);<br />tmp.print();<br />tmp.a=para.a+1;<br />para.print();<br />return &tmp;</p><p>}<br />void main()<br />{<br />Aclass t1(2);<br />Aclass* t2;<br />t2=test(t1);<br />t1.print();<br />t2->print();</p><p>}
結果是
constructor 2
constructor 4
print 4
print 2
destructor 3
print 2
print -858993460
destructor 2
Press any key to continue
臨時對象的指標是不能做傳回值的
對象指標 因沒有指派至記憶體而無所謂建構函式的調用了
#include <iostream><br />using namespace std;</p><p>class Aclass<br />{<br />public:<br />int a;<br />Aclass(int t=0){<br />this->a=t;<br />cout<<"constructor "<<a<<endl;<br />}<br />void print(){<br />cout<<"print "<<this->a<<endl;<br />}<br />~Aclass(){<br />cout<<"destructor "<<a<<endl;<br />}</p><p>};</p><p>Aclass test(Aclass& para)<br />{<br />Aclass* tmp=new Aclass(4);<br />tmp->a=para.a+1;</p><p>return *tmp;<br />}<br />void main()<br />{<br />Aclass t1(2);<br />Aclass t2;<br />t2=test(t1);</p><p>}
如果使用new 動態分配記憶體,析構在delete時才調用
動態變數存在於堆記憶體,必須手動釋放
有一個new就要有一個delete與之對應