本文主要是介绍【C++学习笔记 20】C++中的智能指针,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
智能指针的功能
在上一篇笔记提到了在栈和堆上创建变量的区别,使用new
关键字创建变量时,需要搭配delete
关键字销毁变量。而智能指针的作用就是调用new
分配内存时,不必自己去调用delete
,甚至不用调用new
。 智能指针实际上就是对原始指针的包装。
unique_ptr
最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete
。它名为unique
的原因是这个指针不能被复制,因为赋值该指针意味着有两个指针指向同一个内存,当其中一个指针被销毁,它会释放那块内存,因此指向相同内存的另一个指针,指向的会是一个被释放的内存,因此不能复制unique_ptr
。
举个例子
#include <iostream>
#include <string>
#include <memory>class Entity
{
public:Entity(){std::cout << "Created Entity!" << std::endl;}~Entity(){std::cout << "Destroyed Entity" << std::endl;}
};int main() {{std::unique_ptr<Entity> e(new Entity());}std::cin.get();
}
使用上述代码就可以实现智能指针的功能,值得一提的是,必须显式调用构造函数,因为unique_ptr
是显式定义的。其实有一种更推荐的创建unique_ptr
的方法。
{std::unique_ptr<Entity> e = std::make_unique<Entity>();
}
这样做的主要是出于异常安全考虑。
shared_ptr
如果想要对指针进行引用,可以使用shared_ptr
,它的实现方式取决于编译器和其使用的标准库,大多数会使用引用计数实现。顾名思义,它是一种跟踪统计指针有多少引用的方法,一旦计数为0,它就会被删除。
{std::shared_ptr<Entity> sharedE = std::make_shared<Entity>();
}
可以这样进行创建。在unique_ptr
中不调用new
的原因是异常安全。 shared_ptr
则是因为其会额外分配一块叫做控制块的内存,用以存储引用计数,如果先使用new
,在将new
出来的指针传给shared_ptr
的构造函数,那么就会有两次内存分配,使用make_shared
可以将这两步结合起来,这样效率更高。
举个例子
{std::shared_ptr<Entity> e0;{std::shared_ptr<Entity> sharedE = std::make_shared<Entity>();e0 = sharedE;}
}
当离开内部的作用域时,sharedE
指针并未被摧毁,因为e0
指针保持对它的引用,当离开外层的作用域时,指针才被摧毁。
另外,可以搭配weak_ptr
使用shared_ptr
,其特点在于将指针赋给weak_ptr
不会增加引用计数。它不会保证指针的存活。
使用智能指针可以自动化内存管理,往往非常有用,优先使用unique_ptr
,它的花销更低,其次才是shared_ptr
。
教程来源:The Cherno C++ 教程
这篇关于【C++学习笔记 20】C++中的智能指针的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!