C++中的智能指针及其使用方法

在本文中,我们将讨论C++中的智能指针。什么是智能指针,为什么,以及如何正确使用它们?

null

指针用于访问程序外部的资源,比如堆内存。因此,为了访问堆内存(如果在堆内存中创建了任何内容),需要使用指针。当访问任何外部资源时,我们只使用该资源的一个副本。如果我们对它做任何更改,我们只需在复制的版本中进行更改。但是,如果我们使用指向资源的指针,我们将能够更改原始资源。

普通指针的问题

看看下面的代码。

C++

#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();
}
}


在功能上 享乐 ,它会创建一个指向 长方形 对象物体 长方形 包含两个整数, 宽度 .当函数 享乐 结束时,p将被销毁,因为它是一个局部变量。但是,它消耗的内存不会被释放,因为我们忘记了使用 删除p; 在函数的末尾。这意味着内存不能被其他资源使用。但是,我们不再需要变量,而是需要内存。

在功能上 主要的 , 享乐 在无限循环中调用。这意味着它将继续创造 P .它会分配越来越多的内存,但不会释放它们,因为我们没有释放它。浪费的内存不能再使用了。这是内存泄漏。整个 因此,记忆可能会变得无用。C++11想出了解决这个问题的办法, 智能指针 .

智能指针的介绍

正如我们所知,无意识地不释放指针会导致内存泄漏,从而导致程序崩溃。Java、C#拥有的语言 垃圾收集机制 聪明地释放未使用的内存以便再次使用。程序员不必担心任何内存泄漏。C++11提出了自己的机制 智能指针 。当对象被销毁时,它也会释放内存。所以,我们不需要像智能指针处理它那样删除它。

A. 智能指针 是指针上的包装器类,其运算符为*和->重载。智能指针类的对象看起来像普通指针。但是,不像 正常指针 它可以释放并释放被破坏的对象内存。

这个想法是带指针上课, 析构函数 重载运算符 比如*和->。由于当对象超出作用域时会自动调用析构函数,因此动态分配的内存将自动删除(或者可以减少引用计数)。考虑以下简单 SmartPtr

C++

#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

这只适用于 智力 .那么,我们必须为每个对象创建智能指针?不,有个解决办法, 样板 .如您所见,在下面的代码中 T 可以是任何类型。阅读更多关于 样板 在这里

C++

#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

注: 智能指针在资源管理中也很有用,比如文件句柄或网络套接字。

智能指针的类型

1.独特的

独特的 只存储一个指针。我们可以通过从指针中删除当前对象来指定不同的对象。注意下面的代码。首先是 唯一_指针 指的是 P1 .但是,然后我们移除 P1 分配 P2 现在指针指向 P2 .

unique_ptr

C++14

#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;
}


输出:

5050

2.共享ptr

通过使用 共享ptr 一次可以有多个指针指向这个对象,它将保持 参考计数器 使用 使用_count() 方法

shared_ptr

C++14

#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;
}


输出:

5050502

3.弱ptr

它与shared_ptr更相似,只是它不会维护 参考计数器 .在这种情况下,指针不会在对象上有据点。原因是,如果指针持有该对象并请求其他对象,那么它们可能会形成一个 僵局

weak_ptr

C++库以如下形式提供智能指针的实现 自动_ptr , 独特的 , 共享_ptr和弱_ptr

参考资料: http://en.wikipedia.org/wiki/Smart_pointer

本文的改进是 阿米亚兰安罗特 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论。 它又被改进了一次 AAShakil50 .

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享