C++--智能指针
普通指针创建动态内存的问题:
1.new和new[]的内存需要使用delete和delete []释放。
2.有时忘记释放内存。
3.不知该在何时释放内存。
智能指针的优点:
在不需要对象时自动释放对象,从而避免内存泄漏和其他与内存管理相关的问题。
智能指针有:unique_ptr,shared_ptr和weak_ptr
C++中几种常见的智能指针
std::unique_ptr
独占所有权:unique_ptr 拥有其所指向对象的独占所有权。同一时间内只能有一个 unique_ptr 指向某个对象。
移动语义:当 unique_ptr 被赋值或移动到另一个 unique_ptr 时,原 unique_ptr 会失去对对象的所有权,而新 unique_ptr 会获得所有权。
自定义删除器:可以为 unique_ptr 指定一个自定义的删除器,以在删除对象时执行特定的操作。
不支持复制操作:由于 unique_ptr 拥有独占所有权,因此它不支持复制构造函数和复制赋值操作符。
std::shared_ptr
共享所有权:多个 shared_ptr 可以指向同一个对象,并共享其所有权。当最后一个拥有该对象的 shared_ptr 被销毁或重置时,对象才会被删除。
引用计数:shared_ptr 使用引用计数来跟踪指向某个对象的 shared_ptr 的数量。当引用计数变为0时,对象会被自动删除。
循环引用问题:由于 shared_ptr 的共享所有权特性,如果不当使用可能会导致循环引用问题,从而阻止对象被正确删除。为了解决这个问题,可以使用 std::weak_ptr。
std::weak_ptr
弱引用:weak_ptr 是对 shared_ptr 所管理对象的弱引用,它不增加对象的引用计数。因此,它不会阻止对象被 shared_ptr 删除。
解决循环引用:weak_ptr 通常用于解决由 shared_ptr 引起的循环引用问题。通过使用 weak_ptr 代替其中一个 shared_ptr,可以确保在循环引用中至少有一个指针不会增加引用计数。
访问原始指针:虽然 weak_ptr 本身不拥有对象,但它可以安全地访问对象的原始指针(通过调用 lock() 方法)。如果对象仍然存在,lock() 将返回一个指向该对象的 shared_ptr;否则,将返回一个空的 shared_ptr。
以下是一些可能导致内存泄漏的情况:
循环引用:在使用std::shared_ptr时,如果两个或更多的智能指针相互持有对方的引用(形成循环),则它们将永远不会被释放,从而导致内存泄漏。为了避免这种情况,可以使用std::weak_ptr来打破循环。
自定义删除器:如果你为智能指针提供了一个自定义删除器,并且这个删除器存在缺陷,那么可能会导致内存泄漏。例如,删除器可能只是简单地调用delete,但如果你的对象需要特殊的清理逻辑(如关闭文件句柄或释放其他资源),那么这些资源可能不会被正确释放。
unique_ptr
unique_ptr 独占智能指针。
它独占指向的对象,也就是说,某个时刻只有一个 unique_ptr 指向一个给定对象,当unique_ptr 被销毁时,它所指向的对象也被销毁。
需要包含头文件: #include
class Student { public: string m_name;//学生姓名 Student(const string& name = "") :m_name(name)//构造函数 { cout cout auto p1 = new Student("刘备");//利用new创建一个新对象 //delete p1; //忘记释放对象,出现内存泄漏 return 0; } public: unique_ptr( ); //默认构造函数 explicit unique_ptr( pointer Ptr ); //构造函数,不允许隐式转换 unique_ptr (pointer Ptr, typename remove_reference public: Student(const string& name = ""):m_name(name)//构造函数 { cout cout cout Student* p1 = new Student("刘备"); unique_ptr cout unique_ptr cout public: void operator()(Student* ps) //重载() { cout cout //自定义删除器,普通函数 unique_ptr public: Student(const string& name = ""):m_name(name)//构造函数 { cout cout cout //方法一: shared_ptr p-show(); } void test02(shared_ptr p-show(); } int main() { shared_ptr cout public: void operator()(Student* ps) //重载() { cout cout shared_ptr public: A(){ m_a = new int[10];//动态创建10个元素 cout delete[]m_a;//释放内存 cout public: shared_ptr m_b = new int[10];//动态创建10个元素 cout delete[]m_b;//释放内存 cout auto a = std::make_shared public: A(){ m_a = new int[10];//动态创建10个元素 cout delete[]m_a;//释放内存 cout public: shared_ptr m_b = new int[10];//动态创建10个元素 cout delete[]m_b;//释放内存 cout auto a = std::make_shared