2017-08-25 68 views
3

考慮下面的代碼:C++ - 析構函數被調用的次數比預期

class C1 
{ public: 

     C1(){ cout<<"CONSTR WAS HERE"<<endl; } 

     C1(const C1&ob){ cout<<"COPY CONSTR WAS HERE"<<endl; } 

     ~C1(){ cout<<"DESTR WAS HERE"<<endl; } 
} 

void f1(C1 x){ } 

int main() 
{ 
    C1 c1; 
    f1(c1); 
} 

如果我們運行的代碼,因爲它是我們得到:

CONSTR WAS HERE 
COPY CONSTR WAS HERE 
DESTR WAS HERE 
DESTR WAS HERE 

這是完全可以理解的我的觀點。然而,如果我們修改函數 「F1」 至:

C1 F1(C1 x)的{}

代替

空隙F1(C1 x)的{}

我們得到:

CONSTR WAS HERE 
COPY CONSTR WAS HERE 
DESTR WAS HERE 
DESTR WAS HERE 
DESTR WAS HERE 

,我不太清楚爲什麼。

+11

'C1 f1(C1 x){}'具有未定義的行爲,因爲它實際上並未返回值。 – AndyG

+0

如果你聲明瞭一個函數來返回一些東西(例如,返回類型不是'void'),那麼函數*必須*返回一些東西,否則你將會有[*未定義的行爲*](http://en.cppreference。 com/w/cpp/language/ub)(這會讓你的程序不合格並且無效)。在UB程序中猜測任何類型的行爲是一個有爭議的問題。 –

回答

12

使您的警告:

警告:在函數沒有返回語句,返回非void [-Wreturn型]

你在你的程序中,有undefined behavior這意味着,任何事情都有可能發生。編譯器可能會「在這裏返回一個未定義的C1實例」,這會導致析構函數被調用。

程序可能會崩潰或做別的取決於你的編譯器/標記/臺機器上。

9

修改C1 f1(C1 x){}實際返回的東西,你的輸出將如預期(Demo

C1 f1(C1 x){ return {};} 

構造WAS HERE
COPY構造WAS HERE
構造WAS HERE
DESTR WAS HERE
DESTR在這裏
DESTR在這裏

否則您的代碼會顯示未定義的行爲。