IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 中的智能指针以及如何使用它们 -> 正文阅读

[C++知识库]C++ 中的智能指针以及如何使用它们

在本文中,我们将讨论 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();
	}
}

在函数fun中,它创建一个指向Rectangle对象的指针。对象Rectangle包含两个整数,长度宽度。当函数fun结束时, p 将被销毁,因为它是一个局部变量。但是,它消耗的内存不会被释放,因为我们忘记使用*delete p;*在函数的最后。这意味着内存不会被其他资源免费使用。但是,我们不再需要变量,但我们需要内存。

在函数main中,fun在无限循环中被调用。这意味着它将继续创建p。它会分配越来越多的内存,但不会释放它们,因为我们没有释放它。被浪费的内存不能再使用了。这是内存泄漏。由于这个原因,整个内存可能变得无用。C++11 提出了解决这个问题的方法,Smart Pointer。

智能指针介绍

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

智能指针是指针上的包装类,其中重载了 * 和 -> 等运算符。智能指针类的对象看起来像普通指针。但是,与普通指针不同,它可以解除分配和释放被破坏的对象内存。

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

#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。那么,我们必须为每个对象创建智能指针吗?不,有一个解决方案,模板。在下面的代码中,您可以看到T可以是任何类型。在此处阅读有关模板的更多信息。

#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.unique_ptr

unique_ptr只存储一个指针。我们可以通过从指针中删除当前对象来分配不同的对象。注意下面的代码。首先,unique_pointer指向P1。但是,然后我们删除P1并分配P2,因此指针现在指向P2

unique_ptr

#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多个指针一次可以指向这个对象,并且它将使用use_count()***方法维护一个*引用计数器。

shared_ptr

#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

它与 shared_ptr 更相似,只是它不会维护Reference Counter。在这种情况下,指针在对象上不会有据点。原因是如果假设指针持有对象并请求其他对象,那么它们可能会形成死锁。

弱点

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-04 10:51:31  更:2022-02-04 10:54:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:52:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码