std::enable_shared_from_this
的使用通常遵循以下步骤:
将要使用 shared_from_this()
的类继承自 std::enable_shared_from_this
。
在需要获取指向自身的shared_ptr
的地方,调用 shared_from_this()
函数。
这样做的好处是,即使对象自身是通过裸指针传递给 std::shared_ptr
构造函数的,也可以安全地获取指向自身的 shared_ptr
,避免了潜在的内存泄漏和未定义行为。
#include <iostream>
#include <memory>
class MyClass : public std::enable_shared_from_this<MyClass> {
public:
std::shared_ptr<MyClass> getShared() {
return shared_from_this();
}
};
int main() {
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
std::shared_ptr<MyClass> ptr2 = ptr1->getShared();
if (ptr1 == ptr2) {
std::cout << "Both shared_ptr point to the same object." << std::endl;
} else {
std::cout << "Unexpected behavior!" << std::endl;
}
return 0;
}
在这个示例中,MyClass
继承自 std::enable_shared_from_this
,并提供了一个成员函数 getShared()
,用于获取指向自身的 shared_ptr
。在 main()
函数中,通过make_shared
创建了一个 MyClass
对象,并获取了两个指向该对象的 shared_ptr
,它们使用 getShared()
函数获取了指向同一对象的 shared_ptr
,然后进行了比较,确认它们确实指向同一个对象。
std::shared_ptr
是 C++ 中的智能指针,通过引用计数机制来管理动态分配的对象的生命周期。shared_ptr
的销毁通常意味着它所管理的对象不再被引用,引用计数减为 0,从而释放对象的内存。
shared_ptr
被销毁的时机
shared_ptr
的生命周期结束或被销毁的时机通常分为以下几种情况:
-
shared_ptr
离开作用域: 当一个shared_ptr
变量离开其作用域时,C++ 会自动调用其析构函数,引用计数减 1。如果引用计数变为 0,所管理的对象会被释放。std::shared_ptr<int> ptr = std::make_shared<int>(10); // 当这个代码块结束时,ptr 离开作用域,引用计数会减 1 } // 这里引用计数变为 0,所管理的对象被销毁
-
shared_ptr
被显式重置 (reset()
): 调用shared_ptr::reset()
会将shared_ptr
指向的对象重置。如果此shared_ptr
是该对象的最后一个引用者,则对象会被销毁。std::shared_ptr<int> ptr = std::make_shared<int>(20); ptr.reset(); // 此时引用计数变为 0,管理的对象会被销毁
-
shared_ptr
被赋值新对象: 当一个shared_ptr
被赋值为另一个对象时,原对象的引用计数减少。如果原对象的引用计数变为 0,则原对象会被销毁。std::shared_ptr<int> ptr = std::make_shared<int>(30); ptr = std::make_shared<int>(40); // 原对象的引用计数变为 0,销毁
-
所有
shared_ptr
被销毁或重置: 只要有其他shared_ptr
共享同一个对象,该对象的引用计数不会减为 0。因此,只有当所有shared_ptr
都被销毁或重置时,引用计数才会减为 0,导致对象被销毁。std::shared_ptr<int> ptr1 = std::make_shared<int>(50); std::shared_ptr<int> ptr2 = ptr1; // 引用计数为 2 ptr1.reset(); // 引用计数为 1,管理的对象未销毁 ptr2.reset(); // 引用计数为 0,管理的对象被销毁
shared_ptr
销毁时会发生什么
当 shared_ptr
的引用计数变为 0 时,它的析构函数会被调用,自动释放管理的对象。这个过程确保了动态分配的内存不会发生泄漏。
在 shared_ptr
的析构函数中,它首先会减少引用计数,当引用计数为 0 时,调用 delete
来销毁对象(即释放对象占用的内存)。
总结
shared_ptr
会在以下几种情况下被销毁:
- 当它离开作用域时。
- 当显式调用
reset()
时。 - 当它被赋值为其他对象时。
- 当所有共享同一个对象的
shared_ptr
都被销毁或重置时。
一旦 shared_ptr
的引用计数变为 0,所管理的对象会自动被释放。