析构函数如何在简单程序中工作?
How do destructors work in a simple program?
我不明白这个程序的输出:
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 次调用复制构造函数和一次调用析构函数...
现在说我的主要功能是:
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 更改为:
class A {
public :
A () { cout << "A() " << endl;}
A (const A &) { cout << "A(const &) " << endl;}
~A () { cout << "~A ()" << endl; }
};
您将看到正在调用复制构造函数(因为您提供了一个)。
follow-up 问题的答案。
析构函数与构造函数配对。为什么你期望两个建筑和三个破坏?这在正确的程序中是不可能的。
A b = f(a);
不是赋值(与 a = f(a)
相反),而是构造(copy initialization). You don't see a construction and destruction of a temporary object here thanks to the return value optimization (RVO):允许编译器省略不必要的副本并将 b
构造为如果按 A b(a);
.
在 C++17 之前,此机制是可选的。您可以 compile 使用带有 -std=c++11 -fno-elide-constructors
选项的 GCC 来发现临时代码:
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)
我不明白这个程序的输出:
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 次调用复制构造函数和一次调用析构函数...
现在说我的主要功能是:
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 更改为:
class A {
public :
A () { cout << "A() " << endl;}
A (const A &) { cout << "A(const &) " << endl;}
~A () { cout << "~A ()" << endl; }
};
您将看到正在调用复制构造函数(因为您提供了一个)。
follow-up 问题的答案。
析构函数与构造函数配对。为什么你期望两个建筑和三个破坏?这在正确的程序中是不可能的。
A b = f(a);
不是赋值(与 a = f(a)
相反),而是构造(copy initialization). You don't see a construction and destruction of a temporary object here thanks to the return value optimization (RVO):允许编译器省略不必要的副本并将 b
构造为如果按 A b(a);
.
在 C++17 之前,此机制是可选的。您可以 compile 使用带有 -std=c++11 -fno-elide-constructors
选项的 GCC 来发现临时代码:
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)