实现自己的make_shared
使用shared_ptr实现
#include<bits/stdc++.h>
using namespace std;
//return shared_ptr
template<typename T,typename... Args>//可变参数模板
shared_ptr<T> my_shared_make(Args&&... args){
//形参为右值引用,传给T的构造函数形参使用 std::forward可保留形参属性
// new处新的内存空间,将控制权给shared_ptr构造函数
shared_ptr<T> res(new T(forward<Args>(args)...));
return res;
}
int main(int args,char** argc){
auto ip=my_shared_make<int>(42);
cout<<*(ip.get())<<endl;
cout<<*ip<<endl;
shared_ptr<string> st=my_shared_make<string>(10,'c');
cout<<*st<<endl;
return 0;
}
string s6=string(10,'c');//拷贝初始化,生成一个初始化好的对象,拷贝给s6
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string s;//默认初始化,一个空字符串
string s1("ssss");//s1是字面值“ssss”的副本
string s2(s1);//s2是s1的副本
string s3=s2;//s3是s2的副本
string s4(10,'c');//把s4初始化
string s5="hiya";//拷贝初始化
string s6=string(10,'c');//拷贝初始化,生成一个初始化好的对象,拷贝给s6
//string s(cp,n)
char cs[]="12345";
string s7(cs,3);//复制字符串cs的前3个字符到s当中
//string s(s2,pos2)
string s8="asac";
string s9(s8,2);//从s2的第二个字符开始拷贝,不能超过s2的size
//string s(s2,pos2,len2)
string s10="qweqweqweq";
string s11(s10,3,4);//s4是s3从下标3开始4个字符的拷贝,超过s3.size出现未定义
return 0;
}
make_shared和shared_ptr的区别
struct A;
std::shared_ptr<A> p1 = std::make_shared<A>();
std::shared_ptr<A> p2(new A);
std::shared_ptr
在实现的时候使用的refcount技术,因此内部会有一个计数器(控制块,用来管理数据)和一个指针,指向数据。因此在执行std::shared_ptr<A> p2(new A)
的时候,首先会申请数据的内存,然后申请内控制块,因此是两次内存申请,而std::make_shared<A>()
则是只执行一次内存申请,将数据和控制块的申请放到一起。那这一次和两次的区别会带来什么不同的效果呢?
这使得make_shared效率更高,因为内存分配是代价很高的操作,参数求值的顺序不会异常。
但:
- 构造函数是保护或私有时,无法使用 make_shared
- 使用weak_ptr对象的内存无法及时回收
- 无法像shared_ptr 的构造那样添加一个delete
参考
https://blog.csdn.net/TuxedoLinux/article/details/85042775