动态内存与智能指针
Posted vlyf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态内存与智能指针相关的知识,希望对你有一定的参考价值。
动态内存与智能指针
智能指针分为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"}。
以上是关于动态内存与智能指针的主要内容,如果未能解决你的问题,请参考以下文章