Laz*_*zer 2 c++ shared-ptr static-cast c++11
我是C++样式演员的新手,需要帮助理解下面的代码是如何工作的(这是我写的一些虚拟代码来理解事物).
#include <iostream>
#include <memory>
class A {
public:
A() : a(1) {
std::cout << "Creating A\n";
}
~A() {
std::cout << "Destroying A\n";
}
int a;
};
class B : public A {
public:
B() : b(2) {
std::cout << "Creating B\n";
}
~B() {
std::cout << "Destroying B\n";
}
int b;
};
int main() {
std::shared_ptr<B> objectB(new B());
{
std::shared_ptr<A> (static_cast<A*>(objectB.get()));
std::cout << "End of inner scope\n";
}
std::cout << "End of outer scope\n";
}
Run Code Online (Sandbox Code Playgroud)
它打印
Creating A
Creating B
Destroying A
End of inner scope
End of outer scope
Destroying B
Destroying A
Run Code Online (Sandbox Code Playgroud)
我的理解:
Creating A -> B's ctor calls base class ctor
Creating B -> B's ctor
Destroying A -> ???
End of inner scope
End of outer scope
Destroying B -> B's dtor
Destroying A -> B's dtor calls base dtor
Run Code Online (Sandbox Code Playgroud)
为什么我会得到第一个Destroying A以及到底发生了什么?!A怎么能被摧毁两次?
如果确保输出已刷新(std::endl例如,使用),则得到
创造A.
创造B.
摧毁A.
内部范围结束
外部范围结束
摧毁B.
摧毁A.
双重删除的原因A是你在shared_ptr这里构建一个原始指针:
std::shared_ptr<A> (static_cast<A*>(objectB.get()));
Run Code Online (Sandbox Code Playgroud)
这shared_ptr完全独立于第一个,并有自己的引用计数.因此,当范围结束时,它会尝试删除A它所持有的指针.如果你这样做了:
std::shared_ptr<A>{objectB};
Run Code Online (Sandbox Code Playgroud)
那么你就不会遇到这个问题.注意这里没有必要static_cast.
请注意,A应该有一个virtual析构函数.shared_ptr有一个聪明的破坏机制,这意味着这在这个例子中并不重要,但一般来说,如果要以多态方式删除对象,基类必须有一个虚拟析构函数.
| 归档时间: |
|
| 查看次数: |
156 次 |
| 最近记录: |