Advertisement

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();
    
 	}
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/MGScKTxtdj5Q6XzkEYD8fJuZl0oA.png)

上面代码的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;
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/TGC7E693LzdBZWFoVyfbsr0pvlj5.png)

输出为:

复制代码
    20
    
    cpp
    
    

上面的代码仅仅适用于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;
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/yYNj8ZdDbkaO7BmiJ5W06cquEeTw.png)

输出如下:

复制代码
    20
    
    cpp
    
    

注意:智能指针一般用于管理资源,比如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;
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/fDOdNlwqk8WxUGJt09iyHTBmS6vM.png)

输出:

复制代码
 50

    
 50
    
    
    
    
    cpp
    
    

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;
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/I5bFlAinOGWpSJB3Ct7qcuaRom0K.png)

输出:

复制代码
 50

    
 50
    
 50
    
 2
    
    
    
    
    cpp
    
    

3.weak_ptr

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

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

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

全部评论 (0)

还没有任何评论哟~