class Class {
public:
Class() {std::cout << "Constructor" << '\n';}
~Class() {std::cout << "Destructor" << '\n';}
};
int main() {
std::cout<<"\nNew shared_ptr:\n";
Class C;
std::shared_ptr<Class> ptr(&C);
}
跑完后我有:
New shared_ptr:
Constructor
Destructor
Destructor
为什么?为什么析构函数被调用两次?
答案 0 :(得分:0)
C ++中的原始指针存储对象的地址(指向对象),而C ++中的智能指针用作具有自动删除功能的原始指针的包装。
尽管智能指针通常不复制原始对象,但是在您的情况下,您将传递本地C
的地址作为参数,因此C
的副本将存储在堆中。
总结Class C;
使用堆栈内存,而std::shared_ptr<Class> ptr(&C);
使用堆内存。
在main()
函数的末尾,C
超出范围,因此调用了析构函数。
然后共享指针会自动删除其在堆中的对象,因此将调用其对应的析构函数。
因此有两个析构函数。
答案 1 :(得分:0)
在不使用自定义删除器的情况下提供指向std::shared_ptr
的原始指针意味着shared_ptr
实现将delete
的指针值在没有更多shared_ptr
的情况下拥有指针。在您的示例中,这种情况发生在main
被销毁的ptr
的末尾,因此它尝试delete
的指针等于&C
。这仅对来自new
表达式的指针有效。但是指针不是来自new
;它只是main
中定义的局部变量的地址。因此,这是未定义的行为。