智能指针介绍

智能指针是为了解决程序员创建了资源而忘记释放造成内存泄漏的问题,可减少代码编写过程中的代码长度,减少程序员对资源管理的难度,因而在COM组件及各类插件中有广泛应用。
1、智能指针的原理
  智能指针的原理是利用对象在离开作用域时会调用对象的析构函数,将资源指针封装进类中,并将资源指针的释放过程写入析构函数中,这样就能在对象释放时自动释放资源。

一个管理注册表句柄的智能指针示例如下:

class CSPHKey : public CBase_Uncopy
{
private:
        HKEY        m_hKey;

public:
        CSPHKey(HKEY hKey) 
        {
                m_hKey = hKey;
        }        
        
        virtual        ~CSPHKey() 
        {
                RegCloseKey(m_hKey);               
        }
}

2、智能指针的注意事项

   智能指针由于是用类对象实现的,所以如果有对象复制过程(如函数传值调用),会产生多个智能指针对象,对象释放的过程会多次在析构函数中释放资源,会造成不可预知的意外,故要防止这种情况发生,一般可采取禁止对象复制的方式或者采用引用计数的方式来解决这个问题,下面给出一个Effective C++中的例子,只要继承这个类即可防止对象被复制:

class CBase_Uncopy
{
protected:
 
### 智能指针介绍 智能指针是一种C++对象,它模拟传统的原始指针的行为,但可以自动管理所指向的内存[^1]。智能指针的原理是维护一个引用计数,指向相同内存的智能指针之间赋值或者拷贝都会让内部的引用计数增加,出了某些作用域时引用计数减少,当引用计数等于0时指针自动删除内存对象[^1]。 C++标准库提供了多种智能指针,主要包括`unique_ptr`、`shared_ptr`和`weak_ptr`。`auto_ptr`在C++11中已被弃用,并被`unique_ptr`取代[^3]。`unique_ptr`表示对对象的独占所有权,而`shared_ptr`允许多个指针共享同一个对象,并通过引用计数来管理对象的生命周期[^3]。`weak_ptr`则是一个不控制对象生命周期的智能指针,通常用于解决循环引用问题。 ### 使用方法 使用智能指针时,需要包含`<memory>`头文件。以下是一些常见的使用方法: #### `unique_ptr` `unique_ptr`表示对对象的独占所有权,赋值操作会转移对象所有权。它不能被复制,但可以通过移动语义进行转移。 ```cpp #include <memory> #include <iostream> int main() { std::unique_ptr<int> ptr1(new int(10)); std::cout << *ptr1 << std::endl; // 转移所有权 std::unique_ptr<int> ptr2 = std::move(ptr1); if (ptr1 == nullptr) { std::cout << "ptr1 is null" << std::endl; } std::cout << *ptr2 << std::endl; return 0; } ``` #### `shared_ptr` `shared_ptr`允许多个指针共享同一个对象,并通过引用计数来管理对象的生命周期。当最后一个`shared_ptr`指向的对象被销毁时,对象会被自动删除。 ```cpp #include <memory> #include <iostream> int main() { std::shared_ptr<int> ptr1(new int(10)); std::cout << *ptr1 << std::endl; std::cout << "Use count: " << ptr1.use_count() << std::endl; // 共享所有权 std::shared_ptr<int> ptr2 = ptr1; std::cout << "Use count: " << ptr1.use_count() << std::endl; return 0; } ``` #### `weak_ptr` `weak_ptr`通常用于解决`shared_ptr`之间的循环引用问题。它不增加引用计数,因此不会影响对象的生命周期。 ```cpp #include <memory> #include <iostream> struct B; struct A { std::shared_ptr<B> b_ptr; ~A() { std::cout << "A destroyed" << std::endl; } }; struct B { std::weak_ptr<A> a_ptr; ~B() { std::cout << "B destroyed" << std::endl; } }; int main() { std::shared_ptr<A> a = std::make_shared<A>(); std::shared_ptr<B> b = std::make_shared<B>(); a->b_ptr = b; b->a_ptr = a; return 0; } ``` ### 注意事项 1. **不要使用静态分配对象的指针初始化智能指针**:否则,当智能指针本身被撤销时,它将试图删除指向非动态分配对象的指针,导致未定义的行为[^4]。 2. **避免使用`auto_ptr`**:`auto_ptr`在C++11中已被弃用,它的拷贝操作会将管理权转移给拷贝对象,导致被拷贝对象悬空[^5]。 3. **避免循环引用**:使用`shared_ptr`时,如果两个对象互相持有对方的`shared_ptr`,会导致循环引用,从而无法释放内存。可以使用`weak_ptr`来打破循环[^3]。 4. **正确使用`enable_shared_from_this`**:如果一个类需要从其内部获得`shared_ptr`,应该继承`enable_shared_from_this`,以避免创建额外的`shared_ptr`实例,导致引用计数不一致[^2]。 5. **避免在多个线程中同时访问同一个`shared_ptr`对象**:虽然`shared_ptr`的引用计数是线程安全的,但在多个线程中同时访问同一个`shared_ptr`对象可能会导致数据竞争。可以使用`std::atomic`或锁来保护。 6. **不要手动调用`delete`**:智能指针的设计目的是自动管理内存,手动调用`delete`会破坏智能指针的机制,导致双重删除或内存泄漏。 7. **使用`make_shared`和`make_unique`**:使用`std::make_shared`和`std::make_unique`来创建智能指针,可以确保内存分配和构造一次性完成,避免异常安全问题。 8. **避免将同一个原始指针初始化多个智能指针**:这会导致多个智能指针独立管理同一个内存,最终导致多次删除同一块内存,引发未定义行为。 9. **注意作用域和生命周期**:智能指针的作用域和生命周期决定了它们所管理的对象何时被销毁。确保智能指针的作用域与对象的实际需求一致。 10. **了解智能指针的性能影响**:虽然智能指针简化了内存管理,但它们的引用计数机制可能会带来一定的性能开销。在性能敏感的场景中,应仔细评估使用智能指针的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值