智能指针就这么简单

C++智能指针基础知识及其实现

  • STL中的智能指针简介
    • 先定义一个类
    • auto_ptr(T*)
    • unique_ptr(T*)
    • shared_ptr(T*)
    • weak_ptr(T*)
  • 自己实现一个智能指针
    • 类模板
    • 成员变量
    • 构造函数,析构函数
    • 重载->获取T指针,重载*获取T指针的值
  • 自己实现shared_ptr
    • 新增引用计数成员变量
    • 在构造函数中引用计数初始化
    • 析构函数
      • 新增成员函数
      • 析构函数实现
    • 拷贝构造函数
    • 赋值函数

STL中的智能指针简介

先定义一个类

class A {
public:
	A(int a) { this->a = a; }
	~A() {}
private:
	int a;
};

auto_ptr(T*)

现已废弃。
缺点1:多个指针不能指向同一个,以下代码运行时会报错。

A *a = new A(1);
	auto_ptr ap1(a);
	auto_ptr ap2(a);

缺点2:不能指向数组,以下代码会报错

auto_ptr ap (new int[5]{ 1,2,3,4,5 });

缺点3:没有拷贝构造函数。auto_ptr之间不能相互赋值。

unique_ptr(T*)

独占
只能一个指针指向一个
可以指向数组,下面代码是正确的。

unique_ptr up (new int[5]{ 1,2,3,4,5 });

指针间相互赋值必须使用move

A *a = new A(1);
unique_ptr ap1(a);
unique_ptr ap2=move(ap1);
cout << ap2->a  << endl;

shared_ptr(T*)

可以多个指针共享一个对象
指针之间可以相互赋值
引入了引用计数

A *a = new A(1);
shared_ptr ap1(a);
shared_ptr ap2=ap1;
cout << ap2.use_count()  << endl;

输出了ap2的引用计数为2个

weak_ptr(T*)

weak_ptr的引用计数真实反映了shared_ptr的引用计数。
给他赋值之后不用导致引用计数加一

A *a = new A(1);
shared_ptr ap1(a);
shared_ptr ap2=ap1;
weak_ptr wp = ap1;
cout << wp.use_count()  << endl;

自己实现一个智能指针

类模板

template
class SmartPtr{};

成员变量

一个是T类型的指针
template
class SmartPtr {
private:
T*m_p;
};

构造函数,析构函数

template 
class SmartPtr {
private:
     T*m_p;
public:
	SmartPtr(T*p = 0);
	~SmartPtr();
};

重载->获取T指针,重载*获取T指针的值

template 
class SmartPtr {
public:
	T* m_p;
	
public:
	SmartPtr(T*p = 0);
	T& operator*();
	T* operator->();
	~SmartPtr();
};

实现上面这些就实现了一个普通的auto_ptr了。
如果想要实现shared_ptr,增加引用计数的成员变量。

自己实现shared_ptr

新增引用计数成员变量

template 
class SmartPtr {
private:
	T* m_p;
	size_t * m_Ref;
	
};

在构造函数中引用计数初始化

template
SmartPtr::SmartPtr(T*p) {
	m_p = p;
	m_Ref = new size_t(1);
}

析构函数

当引用计数为0的时候,销毁内存

新增成员函数

void decRef(){
			--*m_Ref;
			if (*m_Ref == 0) {
				delete m_Ref;
				delete m_p;
			}

	}

析构函数实现

template
SmartPtr::~SmartPtr() {
	decRef();
}

拷贝构造函数

两个指向同一块内存,并且引用计数加一

template
SmartPtr::SmartPtr(const SmartPtr& src) {
	m_p = src.m_p;
	m_Ref = src.m_Ref;
	++*m_Ref;
}

赋值函数

右值引用计数加一
左值引用计数减一

让两个指向同一块内存

template
SmartPtr& SmartPtr::operator=(const SmartPtr& rhs) {
	++*rhs.m_Ref;
	decRef();
	m_p = rhs.m_p;
	m_Ref = rhs.m_Ref;
	return *this;
}

你可能感兴趣的:(智能指针就这么简单)