智能指针
准备工作
-
智能指针的作用是为了防止内存泄漏。
-
使用智能指针之前一定要包含头文件memory:
#include<memory>
std::unique_ptr
创建方法
以自定义的Person类为例。
错误创建方法:
std::unique_ptr<Person> p1 = new Person();
//因为没有assignment=的操作
正确创建方法:
//法一:
std::unique_ptr<Person> p(new Person());
//法二:
std::unique_ptr<Person> p = std::make_unique<Person>(); //模板函数
//法三:
auto p = std::make_unique<Person>();
建议使用法二或法三。
权限转移
由于智能指针unique_ptr只允许有一个指针指向一个对象。所以想让另一个指针指向某个对象,理论上需要先将之前的对象的指针指向nullptr,再让该指针指向对象。
实际操作使用到std::move函数,具体操作如下:
auto p1 = std::make_unique<Person>();
std::unique_ptr<Person> p2 = std::move(p1); //auto p2 = std::move(p1);
权限转移经常运用到函数传参之中:
auto p = std::make_unique<Person>();
func(std::move(p));
案例说明
#include<iostream>
#include <memory>
class Person {
public:
int age;
Person() { puts("创建Person"); }
~Person() { puts("析构Person"); }
};
int main() {
puts("开始main函数");
{
auto p1 = std::make_unique<Person>();
p1->age = 10;
auto p2 = std::move(p1);
p2->age = 20;
//p1->age = 30; //错误操作,因为此时p1已经指向了nullptr
}
puts("结束main函数");
system("pause");
return 0;
}
std::shared_ptr
创建方法
法一:
std::shared_ptr<Person> p(new Person());
法二:
std::shared_ptr<Person> p = std::make_shared<Person>();
法三:
auto p = std::make_shared<Person>();
建议使用法二和法三。
拷贝指针
auto p1 = std::make_shared<Person>();
std::shared_ptr<Person> p2 = p1; //auto p2 = p1; //也可以
权限转移
尽管多个shared_ptr可以指向同一个对象,但是同样也可以使用std::move函数转移权限(同shared_ptr)。尽量使用move。
auto p1 = std::make_shared<Person>();
func(std::move(p1));
案例说明
#include<iostream>
#include <memory>
class Person {
public:
int age;
Person() { puts("创建Person"); }
~Person() { puts("析构Person"); }
};
void func(std::shared_ptr<Person> p) {}
int main() {
puts("main函数开始");
{
auto p = std::make_shared<Person>();
puts("进入func函数");
func(p);
puts("结束func函数");
}
puts("main函数结束");
system("pause");
return 0;
}
【说明】当指向某个对象的所有指针都结束生命周期后,该对象才会被析构。
std::weak_ptr
总结
-
尽量使用智能指针。
-
尽量使用unique_ptr。
本文详细介绍了智能指针std::unique_ptr、std::shared_ptr和std::weak_ptr的创建方法、权限转移和案例实战,以防止内存泄漏并优化资源管理。
2189

被折叠的 条评论
为什么被折叠?



