C++ - 析构函数被调用的次数超出预期

3
请注意以下代码:

考虑以下代码段:

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){ }

而不是

void 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
如果你声明一个函数要返回某些东西(即返回类型不是 void),那么这个函数 必须 返回某些东西,否则你将会有未定义行为(这会使你的程序不合法和无效)。对于任何具有 UB 的程序行为进行推测都是没有意义的。 - Some programmer dude
2个回答

12

开启你的警告:

警告:非 void 函数中缺少返回语句[-Wreturn-type]

你的程序存在未定义行为,这意味着任何事情都可能发生。编译器可能会在此处“返回未定义的 C1 实例”,导致析构函数被调用。

程序可能会因你的编译器或编译选项或机器不同而崩溃或做其他任何事情


9

修改 C1 f1(C1 x){} 以返回实际结果,你的输出将会符合预期 (演示)。

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

构造函数在这里。
复制构造函数在这里。
构造函数在这里。
析构函数在这里。
析构函数在这里。
析构函数在这里。

否则你的代码会出现未定义的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接