如何解决析构函数如何在简单程序中工作?
我不理解该程序的输出:
class A {
public :
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
};
A f (A & a) {
return a;
}
int main() {
A a ;
a = f(a);
return 0;
}
我希望
A()
~A()
因为我只创建了一个A
对象:a
。但是,输出是
A()
~A()
~A()
你知道为什么吗?
关注问题
好的,因此,每当调用f
时,我都会构造一个A
的副本,因此我对副本构造函数有1次调用,对析构函数有1次调用...
现在说我的主要功能是:
int main() {
A a ;
A b = f(a);
cout << "returning 0" << endl;
return 0;
}
我希望输出是
A(),A(const A &) (for using f(a))
~A() (for deleting temporary f(a))
returning 0
~A() (destroying B)
~A() (destroying A)
但是输出是
A()
A(const& A)
returning 0
~A()
~A()
那是为什么?
解决方法
您仅显式创建了一个对象,但是您正在此处创建一个对象:
A f (A & a) { return a ;} //when returning A
在复制对象以将其从f传递回来时,该副本是由默认副本构造函数构造的,因为您没有提供该副本构造函数。 如果您将班级更改为此:
class A {
public :
A () { cout << "A() " << endl;}
A (const A &) { cout << "A(const &) " << endl;}
~A () { cout << "~A ()" << endl; }
};
您将看到副本构造函数被调用(就像您提供的那样)。
,后续问题的答案。
析构函数与构造函数配对。您为什么期望有两个构造和三个破坏?在正确的程序中是不可能的。
A b = f(a);
不是赋值(与a = f(a)
相反),而是构造(copy initialization)。借助return value optimization(RVO),您在这里看不到临时对象的构造和破坏:允许编译器排除不必要的副本并构造b
,就像A b(a);
在C ++ 17之前,此机制是可选的。您可以使用带有-std=c++11 -fno-elide-constructors
选项的GCC compile将此代码发现临时的内容:
A() construct (a)
A(const A&) construct a temporary copy of (a)
A(const A&) construct (b) from that temporary
~A() destruct that temporary
returning 0
~A() destruct (b)
~A() destruct (a)
由于C ++ 17强制执行这种类型的复制,因此您始终只能看到两种构造和破坏形式:
A() construct (a)
A(const A&) construct (b) from (a)
returning 0
~A() destruct (b)
~A() destruct (a)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。