C++文档阅读笔记-Smart Pointers in C++ and How to Use Them

Posted IT1995

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++文档阅读笔记-Smart Pointers in C++ and How to Use Them相关的知识,希望对你有一定的参考价值。

此篇博文,介绍了C++中智能指针,为何要使用智能指针,以及如何去用。

指针可使得程序直接访问堆区内存。通过指针,可以直接对原始资源进行修改,也就是说指针指向的就是一手资源。

Problems with Normal Pointers

如下代码:

#include <iostream>
using namespace std;

class Rectangle 
private:
	int length;
	int breadth;
;

void fun()

	// By taking a pointer p and
	// dynamically creating object
	// of class rectangle
	Rectangle* p = new Rectangle();


int main()

	// Infinite Loop
	while (1) 
		fun();
	

上面代码的fun()函数中,创建了Rectangle对象,Rectangle对象包含2个int型成员,分别表示长和宽。当这个函数结束后,指针p并没有被销毁,原因是没有调用delete p,这就造成堆区内存浪费。C++程序有个主旨就是“我们不需变量,我们需要内存”。

在main()函数中,fun()函数被无止境的调用,这也就造成了,无止境的创建p,但不去释放p的资源,导致这块内存程序员无法使用,这就叫内存泄漏。C++11为了解决这一问题,提出了智能指针。

Introduction of Smart Pointers

每一个C++程序员都会不自觉的犯一种错,那就是创建的指针,忘记手动释放,最后导致程序崩溃。像Java、C#都有自己的垃圾回收机制,去回收不用了的堆区内存,避免出现内存泄漏的问题。C++11也推出了自己的一套机制,那就是智能指针。如果程序员想销毁一个对象时,不需要再调用delete方法了,智能指针会自动将其销毁。

其实智能指针就是一个被封装了的类,封装了一些操作符,如*、->。操作智能指针就和普通指针一样。唯一的区别就是普通指针需要自己手动回收资源。

当智能指针在指定的生命周期结束后,会自动释放内存。

智能指针的封装,可以参考如下代码:

#include <iostream>
using namespace std;

class SmartPtr 
	int* ptr; // Actual pointer
public:
	// Constructor: Refer https:// www.geeksforgeeks.org/g-fact-93/
	// for use of explicit keyword
	explicit SmartPtr(int* p = NULL)  ptr = p; 

	// Destructor
	~SmartPtr()  delete (ptr); 

	// Overloading dereferencing operator
	int& operator*()  return *ptr; 
;

int main()

	SmartPtr ptr(new int());
	*ptr = 20;
	cout << *ptr;

	// We don't need to call delete ptr: when the object
	// ptr goes out of scope, the destructor for it is automatically
	// called and destructor does delete ptr.

	return 0;

输出为:

20

上面的代码仅仅适用于int类型,如果需要创建任意类型的对象,就需要使用Template,模板编程如下代码:

#include <iostream>
using namespace std;

// A generic smart pointer class
template <class T>
class SmartPtr 
	T* ptr; // Actual pointer
public:
	// Constructor
	explicit SmartPtr(T* p = NULL)  ptr = p; 

	// Destructor
	~SmartPtr()  delete (ptr); 

	// Overloading dereferencing operator
	T& operator*()  return *ptr; 

	// Overloading arrow operator so that
	// members of T can be accessed
	// like a pointer (useful if T represents
	// a class or struct or union type)
	T* operator->()  return ptr; 
;

int main()

	SmartPtr<int> ptr(new int());
	*ptr = 20;
	cout << *ptr;
	return 0;

输出如下:

20

注意:智能指针一般用于管理资源,比如handles和Sockets,如文件句柄、TCP套接字。

Types of Smart Pointers

1.unique_ptr

unique_ptr存储了单独的一个指针。可以把当前智能指针的对象移除,添加新的对象。如下图所示,unique_pointer P1指向了一个object,只有将P1中的object移除后P2才能指向object。

代码如下:

#include <iostream>
using namespace std;
#include <memory>

class Rectangle 
	int length;
	int breadth;

public:
	Rectangle(int l, int b)
		length = l;
		breadth = b;
	

	int area()
		return length * breadth;
	
;

int main()

	unique_ptr<Rectangle> P1(new Rectangle(10, 5));
	cout << P1->area() << endl; // This'll print 50

	// unique_ptr<Rectangle> P2(P1);
	unique_ptr<Rectangle> P2;
	P2 = move(P1);

	// This'll print 50
	cout << P2->area() << endl;

	// cout<<P1->area()<<endl;
	return 0;

输出:

50
50

 

2.shared_ptr

多个shared_ptr可以在同一时间指向1个object,并且提供了计数功能,记录这个对象被多少个shared_ptr指向。调用的方法是use_count()。

代码如下:

#include <iostream>
using namespace std;
#include <memory>

class Rectangle 
	int length;
	int breadth;

public:
	Rectangle(int l, int b)
	
		length = l;
		breadth = b;
	

	int area()
	
		return length * breadth;
	
;

int main()


	shared_ptr<Rectangle> P1(new Rectangle(10, 5));
	// This'll print 50
	cout << P1->area() << endl;

	shared_ptr<Rectangle> P2;
	P2 = P1;

	// This'll print 50
	cout << P2->area() << endl;

	// This'll now not give an error,
	cout << P1->area() << endl;

	// This'll also print 50 now
	// This'll print 2 as Reference Counter is 2
	cout << P1.use_count() << endl;
	return 0;

 输出:

50
50
50
2

3.weak_ptr

这个weak_ptr就是shared_ptr的简化版,就是删除了其指向计数的功能。

C++提供的智能指针有4个分别是:auto_ptr、unique_ptr、shared_ptr、weak_ptr

估计是auto_ptr太简单了,所以才没有相关介绍。

 

以上是关于C++文档阅读笔记-Smart Pointers in C++ and How to Use Them的主要内容,如果未能解决你的问题,请参考以下文章

C++文档阅读笔记-Smart Pointers in C++ and How to Use Them

std::vector of objects / pointers / smart pointers to pass objects(总线错误:10)?

Move语义和Smart Pointers先导(以一个例子说明)

C++文档阅读笔记-Understanding nullptr in C++

C++文档阅读笔记-Understanding nullptr in C++

C++文档阅读笔记-Tuples in C++