2017-08-25 41 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在这里

否则您的代码会显示未定义的行为。