[英]When the object destructed while I pass the argument by-value?
给出以下代码:
#include <iostream>
using namespace std;
class A {
public:
A() {
}
A(const A& a) {
cout << "A copy ctor" << endl;
}
virtual ~A() {
cout << "A dtor" << endl;
}
virtual void type() const {
cout << "This is A" << endl;
}
};
class B: public A {
public:
virtual ~B() {
cout << "B dtor" << endl;
}
virtual void type() const {
cout << "This is B" << endl;
}
};
A f(A a) {
a.type();
return a;
}
const A& g(const A& a) {
a.type();
return a;
}
int main() {
A *pa = new B();
cout << "applying function f:" << endl;
f(*pa).type();
cout << "~~~ delete: ~~~" << endl;
delete pa;
return 0;
}
我得到以下输出:
应用函数f:
副本ctor
这是一个
副本ctor
这是一个
一个dtor
一个dtor
~~~删除:~~~
B dtor
一个dtor
但我不明白。 它看到,虽然我们从存在f
对象有没有破坏。 为什么它没有被破坏? (毕竟,我们超出了函数的范围,因此它必须被销毁,不是吗?)
注意:我强调了有问题的行(我不明白它为什么按此顺序发生)
我们转到函数f,此时,我们调用copy c'tor并打印“A copy ctor”(Ok),之后,我们返回函数f并转到type(),然后,它是打印“这是A”,现在我们从函数f中取出,所以我们调用copy c'tor,因此将打印“A copy ctor”,但是,现在,析构函数没有被调用(当我们从功能f)..?
我认为输出将如下(根据上面的描述):
应用函数f:
副本ctor
这是一个
副本ctor (逃避type
)
一个dtor (从type
逃脱)
这是A (主要)
~~~删除:~~~
B dtor
一个dtor
C ++标准允许在函数范围内或在调用范围内销毁按值函数参数。
如果在调用范围内,它在完整表达式的末尾被销毁(通常是;
)。 如果在函数内,则在构造返回值并销毁自动存储本地之后销毁它。
A *pa = new B();
创建B
,具有A
子对象基础。
cout << "applying function f:" << endl;
f(*pa)//.type();
创建*pa
切片副本作为f
的参数。 输出是A copy ctor\\n
。
A f(A a) {
a.type();
return a;
}
A .type
。 在A
的实例上调用。 请注意,此A
是*pa
的副本,但它只是*pa
的A
部分的副本。
输出为This is A
,后跟A(A&&)
移动ctor,后跟A dtor
。 在你的情况下,你有一个复制ctor而不是一个移动ctor,所以它被称为。 不能省略此复制/移动,因为您不能从函数参数中删除。 输出是A copy ctor
。
此时,编译器可以可选地将A
f
的参数的A
存档。 你的编译器不破坏变元到f
这里。
f(*pa).type();
f
返回的临时A
现在调用了.type()
。 这里没有多态性; 直接调用方法A::type()
。 输出是This is A
然后我们到达完整表达的末尾。
现在,通过返回的临时f
被破坏,随后的参数f
如果前面没有被破坏。 所以输出是A dtor
。
cout << "~~~ delete: ~~~" << endl;
delete pa;
B
对象*pa
被销毁,然后内存被回收。 由于~A
是虚拟的,因此在*pa
上调用正确的析构函数。
输出为B dtor\\nA dtor\\n
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.