动态内存与智能指针

动态内存与智能指针

智能指针分为shared_ptr、unique_ptr、weak_ptr,他们负责自动释放所指向的对象,shared_ptr允许多个指针指向同一个对象,unique_ptr独占所指向的对象,weak_ptr是一种弱引用,指向shared_ptr所管理的对象,他们都定义在memory头文件中。

shared_ptr类

​ 智能指针也是模板,创建智能指针:

shared_ptr<string> p1;	//可以指向string
shared_ptr<list<int>> p2;	//可以指向int的list
shared_ptr<T> p;	//指向T

​ 默认初始化的智能指针中保存着一个空指针。智能指针的使用方法与普通指针相似,解引用智能指针返回它指向的对象。

p.get();	//返回p中保存的指针
swap(p,q); p.swap(q);	//交换p和q中的指针

shared_ptr独有的操作:

make_shared<T>(args);	//返回一个使用args初始化的T类型的对象的shared_ptr
shared_ptr<T> p(q);		//p是q的拷贝,递增q中的引用计数,递减p中的引用计数,引用计数为0,就释放管理的内存
p.unique();				//若p.use_count()为1,返回true,否则为false
p.use_count();		//返回与p共享对象的智能指针数,可能很慢

make_shared函数

​ 该函数在动态内存中分配一个对象并返回指向该对象的shared_ptr,定义在memory中:

shared_ptr<int> p3=make_shared<int>(42);	//指向值为42的int的shared_ptr
shared_ptr<string> p4=make_shared<string>(10,"9");	//指向值为“999999999”的string
auto p5 = make_shared<int>();	//值初始化为0

该函数使用参数构造给定类型的对象。

智能指针的使用

​ 当指向一个对象的最后一个shared_ptr被销毁时,shared_ptr会自动通过自己的析构函数销毁此对象。看下面的StrBlob类,Strblob类通过shared_ptr实现类对象之间共享底层数据。

StrBlob.h

#include <vector>
#include <memory> //share_ptr,unique_ptr
#include <string>

//Strblob类通过shared_ptr实现类对象共享底层数据
//委托vector完成部分操作
class StrBlob
{
public:
    using size_type = std::vector<std::string>::size_type;
    StrBlob();
    //使用可变形参列表
    //未使用explicit的initializer_list,可以在需要StrBlob对象时使用列表进行隐式类型转换,如作为函数的参数
    StrBlob(std::initializer_list<std::string> il);
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    //添加和删除元素
    void push_back(const std::string &s) const { data->push_back(s); }
    void pop_back();
    //元素访问
    std::string &front();
    const std::string &front() const;
    std::string &back();
    const std::string &back() const;

private:
    std::shared_ptr<std::vector<std::string>> data;
    //若data[i]不合法,就抛出一个异常
    void check(size_type i, const std::string &msg) const;
};

StrBlob.cpp

#include <iostream>
#include "StrBlob.h"

using namespace std;
//make_shared用其参数构造给定类型的对象,返回动态内存的地址
inline StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}

inline StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}

inline void StrBlob::check(size_type i, const string &msg) const
{
    if (i >= data->size())
        throw out_of_range(msg);
}

inline string &StrBlob::front()
{
    check(0, "front on empty StrBlob");
    return data->front();
}
//需要对const进行重载,const对象只能调用const成员函数
//非const对象只能调用非const成员函数
inline const string &StrBlob::front() const
{
    check(0, "front on empty StrBlob");
    return data->front();
}

inline string &StrBlob::back()
{
    check(0, "back on empty StrBlob");
    return data->back();
}

inline const string &StrBlob::back() const
{
    check(0, "back on empty StrBlob");
    return data->back();
}

inline void StrBlob::pop_back()
{
    check(0, "pop on empty StrBlob");
    data->pop_back();
}

int main()
{
    StrBlob b1;
    {
        StrBlob b2 = {"a", "an", "the"};
        b1 = b2;
        b2.push_back("about");
    }

    return 0;
}

最终b1={"a", "an", "the","about"}。

posted @ 2019-10-19 18:16  ManateeFan  阅读(193)  评论(0编辑  收藏  举报