详解请参照
    
     智能指针详解
    
   
    
     本文主要依据C++ primer的基础知识分析智能指针,并最后给出智能指针的实现;
    
   
    
     shared_ptr
    
   
- shared_ptr允许多个指针指向同一个对象
- shared_ptr是实现为模板,当创建一个智能指针时,必须提供额外的信息—-指针可以指向的类型;
- 
     最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr;
 - 
       
 shared_pre<int> p = make_shared<int>(42);
 
- shared_ptr的析构函数会递减它所指向的对象的引用计数,如果引用计数变为0,shared_ptr的析构函数就会销毁对象,并释放它所占用的内存;
- shared_ptr在无用之后仍然保留的一种可能是,将shared_ptr存放在一个容器中,随后重排了容器,从而不再需要某些元素,在此情况下,应该确保用erase删除那些不再需要的shared_ptr元素;
 
- 
       
    
     直接管理内存
    
   
- 
默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象将是未定义的,而类类型对象将用默认构造函数进行初始化; - 值初始化的内置类型对象有着良好定义的值,而默认初始化的对象的值则是未定义的;
- 用new分配const 对象是合法的,一个动态分配的const 对象必须进行初始化,想要释放一个const 动态对象,只要delete 指向它的指针即可;
- 由内置指针(而不是智能指针)管理的内存在被显式释放前一直都会存在;
 
- 
使用new和delete管理动态内存存在三个常见问题: - 忘记delete内存;
- 使用已释放掉的对象;
- 同一块内存释放两次;
 
- 动态内存的一个基本问题是可能有多个指针指向相同的内存,在delete 内存之后重置指针的方法只对这个指针有效,对其他任何仍指向(已释放的)内存的指针是无作用的;
    
     shared_ptr和new结合使用
    
   
- 
可以用new返回的指针初始化智能指针, 
 
 必须使用直接初始化的形式初始化一个智能指针:
 - 
       
 shared_ptr<int> p(new int(1024));
 
- 一个用来初始化智能指针的普通指针必须指向动态内存;
- 
       
 当将一个shared_ptr 绑定到一个普通指针时,就将内存的管理责任交给了这个shared_ptr,一旦这样做了,就不应该再使用内置指针来访问来访问这个shared_ptr 所指向的内存;
 
 - 使用内置指针访问一个智能指针所负责的对象是很危险的,因为我们无法知道对象何时被销毁;
 
- 
       get用来将指针的访问权限传递给代码,
 
 只有在确定代码不会delete指针的情况下才能使用get。特别是,永远不要用get初始化另一个智能指针或为另一个智能指针赋值;
 
 
- 
       
- 
智能指针可以提供对动态分配的内存安全又方便的管理,但这建立在正确使用的前提下,为了正确使用智能指针,必须坚持一些基本规范: - 不使用相同的内置指针值初始化(或reset)多个智能指针;
- 不delete get()返回的指针;
- 不使用get() 初始化或reset 另一个智能指针;
- 如果使用get() 返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了;
- 如果你使用智能指针管理的资源不是new 分配的内存,记住传递给它一个删除器;
 
    
     智能指针的简单实现:
    
   
#include<iostream>
using namespace std;
template<typename T>
class SmartPointer{
private:
    T* ptr;
    size_t* reference_count;
    void releaseCount(){
        if (ptr){
            (*reference_count)--;
            if ((*reference_count) == 0){
                delete ptr;
                delete reference_count;
            }
        }
    }
public:
    SmartPointer(T* p = 0) :ptr(p), reference_count(new size_t){
        if (p)*reference_count = 1;
        else *reference_count = 0;
    }
    SmartPointer(const SmartPointer& src){
        if (this != &src){
            ptr = src.ptr;
            reference_count = src.reference_count;
            (*reference_count)++;
        }
    }
    SmartPointer& operator=(const SmartPointer& src){
        if (ptr == src.ptr)return *this;
        releaseCount();
        ptr = src.ptr;
        reference_count = src.reference_count;
        (*reference_count)++;
        return *this;
    }
    T* operator*(){
        return (*ptr);
    }
    T* operator->(){
        return ptr;
    }
    ~SmartPointer(){
        if (--(*reference_count) == 0){
            delete ptr;
            delete reference_count;
        }
    }
    size_t get_reference(){
        return *reference_count;
    }
};
int main(){
    SmartPointer<char> cp1(new char('a'));
    cout << "cp1.reference_count = " << (cp1.get_reference()) << endl;
    SmartPointer<char> cp2(cp1);
    cout << "cp1.reference_count = " << (cp1.get_reference()) << endl;
    cout << "cp2.reference_count = " << (cp2.get_reference()) << endl;
    SmartPointer<char> cp3 = cp2;
    cout << "cp2.reference_count = " << (cp2.get_reference()) << endl;
    cp3 = cp1;
    cout << "cp3.reference_count = " << (cp3.get_reference()) << endl;
    cp3 = cp3;
    SmartPointer<char> cp4(new char('b'));
    cp3 = cp4;
    cout << "cp4.reference_count = " << (cp4.get_reference()) << endl;
    cout << "cp3.reference_count = " << (cp3.get_reference()) << endl;
    cout << "cp2.reference_count = " << (cp2.get_reference()) << endl;
    system("pause");
    return 0;
}
    
     unique_ptr
    
   
- 
     某个时刻只能有一个unique_ptr 指向一个给定对象,定义一个unique_ptr时,需要将其绑定到一个new 返回的指针上,初始化unique_ptr必须采用直接初始化形式;
 - unique_ptr 不支持普通的拷贝或赋值操作;
- 可以通过release 或 reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique_ptr;
- unique_ptr 默认情况下用delete 释放它所指向的对象,也可以提供一个指定类型的删除器;
 
 
版权声明:本文为u010150046原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
