C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】

老规矩,先问题后文章:

为什么要有智能指针以及它的好处是什么、智能指针是在怎么工作的、智能指针的操作;

1:为什么要有智能指针:

要知道,内存泄漏是非常严重的后果,如果new出来的空间没在合适的时间delete,那么很容易出现bug或者内存泄漏,而合适地用new和delete又是一个特别难的工作,所以C++就推出了智能指针这个概念,其是为了方便程序员管理内存。

大量使用智能指针代替new、delete函数,可以大大地提高程序的稳定性;

2:智能指针是怎么工作的:

个人理解为智能指针是将原始指针封装起来,并结合new、delete、一些必要的函数,因为有delete的参与,所以智能指针可以在适合的时候自动释放;

先介绍智能指针的两个主力:unique、share

unique:

我们先定义一个unique指针:

#include
#include
#include

int main() {

	{
		std::unique_ptr a = std::make_unique(10);
	}

}

为了某种目的,本菜用一个空作用域将指针围起来;

如果程序出了空作用域,那么系统会自动调用delete函数,将指针和其指向的内容给释放掉;

如果我们将a赋值给其他指向同类型的unique指针:

#include
#include
#include

int main() {

	{
		std::unique_ptr a = std::make_unique(10);
		auto b=a;
	}

}

报错:

 因为unique的一个特征就是不能有两个指针指向同一个对象,这个特性也导致unique指针不能作为实参传入函数当中;

这种看似无法理解的机制是因为如果多个unique指针指向同一个对象,当其中一个unique指针被释放时,其对象也会被释放,也就是说其他指向这个对象的指针将成为野指针;

下面来看看智能指针自动释放的功能:

#include
#include
#include

class temp {
public:
	temp() {
		std::cout << "Created" << std::endl;
	}
	~temp() {
		std::cout << "Destroyed" << std::endl;
	}
};

int main() {

	{
		std::unique_ptr a = std::make_unique();
	}

}

运行结果:

C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】_第1张图片

 这里我们没有用delete函数,系统就自动释放指针和指向的对象了;

如果我们想要将智能指针传入函数当中,那么我们就需要share指针了:

share指针允许多个share指针指向同一个对象,而且实例化一个share指针时会多出一些内存开销,这些内存会实现一个功能,即引用计数,这个引用计数会记录有多少个share指针指向该对象,当引用计数发现没有指向该对象的指针时,系统就会将该对象释放;

看下面这段代码:

#include
#include
#include

class temp {
public:
	temp() {
		std::cout << "Created" << std::endl;
	}
	~temp() {
		std::cout << "Destroyed" << std::endl;
	}
};

int main() {

	std::shared_ptr a = std::make_shared();

	{
		std::shared_ptr b = a;
	}
	getchar();
}

运行结果【程序停留在getchar()部分】

C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】_第2张图片

 说明b指针的释放并没有导致b指向的对象被释放,因为还有一个a指针指向该对象,引用计数不为0;

但是如果我们这样写:

#include
#include
#include

class temp {
public:
	temp() {
		std::cout << "Created" << std::endl;
	}
	~temp() {
		std::cout << "Destroyed" << std::endl;
	}
};

int main() {
	{
		std::shared_ptr a = std::make_shared();

		{
			std::shared_ptr b = a;
		}
	}
	getchar();
}

运行结果为:

C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】_第3张图片

 因为到达getchar函数时,两个指针都被释放了,所以对象也跟着被释放了;

然后来谈谈引用计数:

引用计数说白了,就是检测有多少个share指针指向同一个对象,如果为0的话,那么就将调用delete函数将对象清除;

有以下几种情况可以改变引用计数:

(1)当指针方向改变时,引用计数会减小;

(2)当指针被释放时,引用计数会减小;

(2)当指针指向对象时,引用计数会增加;

看以下代码【use_count()函数是share内置的一种函数,功能是返回有多少个share指针指向该对象】

#include
#include
#include

class temp {
public:
	temp() {
		std::cout << "Created" << std::endl;
	}
	~temp() {
		std::cout << "Destroyed" << std::endl;
	}
};

void get(std::shared_ptr mid) {

	std::cout << mid.use_count() << std::endl;

}

int main() {
	{
		std::shared_ptr a = std::make_shared();
		get(a);
		{
			std::shared_ptr b = a;
			get(b);
			
		}
		get(a);
	}
	getchar();
}

运行结果:

C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】_第4张图片

这是因为将a传入函数时,函数会生成一个share指针形参,并将a赋值给形参,这个时候就有两个share指针指向同一个对象了,而将a赋值给b时,又多出一个,当b超出作用域时,就少了一个; 

当然,有时候我们会希望用一个指向由share指针指向的对象时,不引起share指针引用计数的改变,那么我们就可以用weak指针了,这个指针是为了搭配share指针而产生的。如果我们将上述代码中的形参改为weak指针,那么运行结果为:

C++学习笔记:三种智能指针【Share、Unique、Weak】【Cherno】_第5张图片

 好了~这些就是简单的智能指针介绍了,以后本菜还会继续更新;

你可能感兴趣的:(C++,智能指针,shared,weak,unique)