初始化
共享智能指针是指多个智能指针可以同时管理同一块有效的内存,共享智能指针 share_ptr 是一个模板类,如果进行初始化有三种方式如下:- 通过构造函数初始化
- std::make shared 辅助函数
- reset方法
构造函数初始化
//使用智能指针管理一块 int 型的堆内存
shared_ptr<int> ptrl(new int(520));
cout<<"ptr1管理的内存引用计数:"<<ptr1.use_count()<< endl;
//使用智能指针管理一块字符数组对应的堆内存
shared_ptr<char> ptr2(new char[520]);
cout<<"ptr2 管理的内存引用计数:"<<ptr2.use_count()<<endl;
shared_ptr<int> ptr3;
cout<<"ptr3 管理的内存引用计数:"<<ptr3.use count()<<endl;
// 创建智能指针对象,初始化为空
shared_ptr<int> ptr4(nullptr);
cout<<"ptr4管理的内存引用计数:"<<ptr4.use count()<< endl;
/*打印结果如下:
ptr1 管理的内存引用计数:1
ptr2 管理的内存引用计数:1
ptr3 管理的内存引用计数:0
ptr4 管理的内存引用计数:0*/
/*如果智能指针被初始化了一块有效内存,那么这块内存的引用计数+1,
如果智能指针没有被初始化或者被初始化为 nullptr 空指针,引用计数为 0。
另外,不要使用一个原始指针初始化多个shared_ptr。*/
#include <iostream>
#include <memory>
using namespace std;
int main() {
int* raw_ptr = new int(10);
shared_ptr<int> sp1(raw_ptr);
shared_ptr<int> sp2(raw_ptr);
// 在这里,sp1和sp2各自维护自己的引用计数,它们不知道彼此的存在
// 当sp1的引用计数归零时,它会释放raw_ptr指向的内存
// 但是此时sp2还在使用这个内存,这就会导致错误,二次释放问题
return 0;
}
拷贝和移动构造函数初始化
当一个智能指针被初始化之后,就可以通过这个智能指针初始化其他新对象。在创建新对象的时候,对应的拷贝构造函数或者移动构造函数就被调用了
//构造函数
shared_ptr<int> ptrl(new int(520));
cout<<"ptr1 管理的内存引用计数:"<<ptrl.use count()<< endl;
//拷贝构造函数
shared_ptr<int> ptr2(ptrl);
cout<<"ptr2 管理的内存引用计数:"<<ptr2.use count()<< endl;
shared_ptr<int>ptr3=ptrl;
cout <<"ptr3 管理的内存引用计数:"<<ptr3.use count()<<endl;
//移动构造函数
//移动构造会把ptr1的资源移动到ptr4,ptr1会变成一个空指针,不在管理原来的资源,所以引用计数不增加
shared_ptr<int>ptr4(std::move(ptrl));
cout<<"ptr4管理的内存引用计数:"<<ptr4.use count()<< endl;
std::shared_ptr<int>ptr5=std::move(ptr2);
cout<<"ptr5 管理的内存引用计数:"<< ptr5.use count()<<endl;
/*打印结果如下:
ptr1管理的内存引用计数:1
ptr2管理的内存引用计数:2
ptr3管理的内存引用计数:3
ptr4管理的内存引用计数:3
ptr5管理的内存引用计数:3*/
std::make shared 初始化
通过 c++11 提供的 std::make shared()就可以完成内存对象的创建并将其初始化给智能指针
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class Test{
public:
Test(){
cout<< "无参构造函数"<< endl;
}
Test(int x){
cout<<"int 类型构造函数"<< x<< endl;
}
Test(string str){
cout <<"string 类型的构造函数"<<str<< endl;
}
~Test(){
cout<<"析构函数"<< endl;
}
};
int main(){
// 使用智能指针管理一块 int 型的堆内存,内部引用计数为 1
shared_ptr<int>ptrl=make shared<int>(520);
cout<<"ptr1管理的内存引用计数:"<<ptr1.use_count()<< endl;
shared_ptr<Test>ptr2=make shared<Test>();
cout<<"ptr2 管理的内存引用计数:"<<ptr2.use_count()<< endl;
shared_ptr<Test>ptr3 =make shared<Test>(520);
cout<<"ptr3 管理的内存引用计数:"<<ptr3.use_count()<< endl;
shared_ptr<Test>ptr4 = make shared<Test>("QQQQ");
cout<<"ptr4管理的内存引用计数:"<<ptr4.use_count()<< endl;
shared_ptr<Test>ptr5(new Test(200));
cout<<"ptr5 的引用计数为:"<<ptr5.use_count()<< endl;
return 0;
}
/*打印结果如下:
ptr1管理的内存引用计数:1
无参构造函数
ptr2管理的内存引用计数:1
int类型构造函数 520
ptr3管理的内存引用计数:1
string类型的构造函数 QQ22
ptr4管理的内存引用计数:1
int类型构造函数
ptr5管理的内存引用计数:1
析构函数
析构函数
析构函数
析构函数*/
如果使用拷贝的方式初始化共享智能指针,这两个对象会同时管理同一块内存,堆内存对应的引用技术也会增加。如果使用移动构造的方式初始化智能指针对象,只是转让了内存的所有权,管理内存的对象不会增加,因此内存引用技术不会增加。
reset方法初始化
#include <iostream>
#include <string>
#include <memory)
using namespace std;
int main(){
// 使用智能指针管理一块 int 型的堆内存,内部引用计数为 1
shared_ptr<int>ptrl=make shared<int>(520);
shared_ptr<int>ptr2=ptrl;
shared_ptr<int> ptr3=ptrl;
shared_ptr<int>ptr4=ptrl;
cout<<"ptr1 管理的内存引用计数:"<< ptrl.use count()<< endl;
cout<<"ptr2 管理的内存引用计数:"<<ptr2.use count()<< endl;
cout<<"ptr3 管理的内存引用计数:"<<ptr3.use count()<< endl;
cout<<"ptr4管理的内存引用计数:"<<ptr4.use count()<< endl;
ptr4.reset();
cout<<"ptr1 管理的内存引用计数:"<< ptrl.use count()<< endl;
cout<<"ptr2 管理的内存引用计数:"<<ptr2.use count()<< endl;
cout<<"ptr3 管理的内存引用计数:"<<ptr3.use count()<< endl;
cout<<"ptr4管理的内存引用计数:"<<ptr4.use count()<< endl;
shared ptr<int> ptr5;
ptr5.reset(new int(250));
cout<<"ptr5 管理的内存引用计数:"<<ptr5.use count()<< endl;
return 0;
}
/*打印结果如下
ptr1管理的内存引用计数:4
ptr2 管理的内存引用计数:4
ptr3 管理的内存引用计数:4
ptr4 管理的内存引用计数:4
ptr1 管理的内存引用计数:3
ptr2 管理的内存引用计数:3
ptr3 管理的内存引用计数:3
ptr4 管理的内存引用计数:0
ptr5 管理的内存引用计数:1*/
对于一个未初始化的共享智能指针,可以通过 reset 方法来初始化,当智能指针中有值得时候,调用reset 会使引用计数减 1.
获取原始指针
get()函数
nt main(){
shared_ptr<int> p(new int);
*p = 100;
cout << *p.get()<<" "<< *p<< endl;
return 0
}
//100 100
share_ptr实现
#pragma once
#include<iostream>
using namespace std;
template<typename T>
class Ref
{
T* p;
int n;
public:
Ref() {
p = nullptr;
n = 0;
}
Ref(T* p) {
this->p = p;
n = 1;
}
void increase() {
if(p) n++;
}
void reduce() {
if(n>0) n--;
if (n == 0) {
delete p;
delete this;
}
}
int useCount() {
return n;
}
T* get() {
return p;
}
};
template<typename T>
class Shared_ptr
{
Ref<T>* r;
public:
Shared_ptr() {
r = new Ref<T>();
}
Shared_ptr(T* p) {
r = new Ref<T>(p);
}
Shared_ptr(const Shared_ptr& o) {
this->r = o.r;
if(r->get()) r->increase();
}
Shared_ptr(Shared_ptr&& o) {
this->r = o.r;
o.r = nullptr;
}
~Shared_ptr() {
if(r) r->reduce();
}
Shared_ptr& operator=(const Shared_ptr& other) {
r->reduce();
this->r = other.r;
if(r->get()) this->r->increase();
return *this;
}
Shared_ptr operator=(Shared_ptr&& other) {
r->reduce();
this->r = other.r;
other.r = nullptr;
return *this;
}
int use_Count() {
if (r) return r->useCount();
else return 0;
}
T* get() {
return r->get();
}
void reset() {
r->reduce();
r = nullptr;
}
void reset(T* p) {
r->reduce();
r = new Ref<T>(p);
}
T& operator*() {
return *(r->get());
}
T* operator->() {
return r->get();
}
};
标签:初始化,cout,share,智能,Shared,shared,ptr,指针
From: https://blog.csdn.net/2401_88249494/article/details/144359321