智能指针是一种C++语言中的智能化内存管理工具,是一种用来管理动态分配的对象的指针。它的作用是自动化管理内存的分配和释放,以避免内存泄漏和悬空指针的问题。
智能指针是C++11标准中引入的一个新特性,它们是通过模板类来实现的。
C++中的智能指针主要有三种:unique_ptr、shared_ptr和weak_ptr。
使用智能指针可以避免手动管理内存和手动释放对象的问题,可以提高代码的可靠性和安全性。但是需要注意的是,使用智能指针也可能会带来一些性能上的损失,因为智能指针需要进行额外的计数和管理工作。
一种共享指针,是多线程安全的智能指针,它可以使多个指针拥有对同一个对象的控制权,即多个指针可以共享同一个对象。
当最后一个shared_ptr对象被销毁时,它所管理的对象也会被销毁。
使用shared_ptr要特别注意循环引用的问题,即两个对象相互引用,导致无法被销毁。
同时,shared_ptr还提供了自定义删除器的功能,可以在释放资源时调用自定义的函数。
每个 shared_ptr 对象在内部指向两个内存位置:
1、指向对象的指针。
2、用于控制引用计数数据的指针。
每当有一个新的shared_ptr对象指向同一块内存时,引用计数会自增,当某个shared_ptr对象超出作用域或被显式地设置为nullptr时,引用计数会自减,当引用计数降为0时,shared_ptr便会自动释放其持有的内存。
int *num = new int(23);
std::shared_ptr<int> p1(num);
std::shared_ptr<int> p2(p1); // 正确使用方法
std::shared_ptr<int> p3(num); // 不推荐
std::shared_ptr<int> ptr_1 = make_shared<int>();
std::shared_ptr<int> ptr_2 (ptr_1);
#include
#include
int main() {
int x = 12;
std::shared_ptr<int> ptr(&x);
return 0;
}
#include
class MyClass {
public:
std::shared_ptr<MyClass> another_instance;
MyClass() {std::cout << "Creating MyClass instance\n"; }
~MyClass() {std::cout << "Destroying MyClass instance\n"; }
};
int main() {
std::shared_ptr<MyClass> instance1 =
std::make_shared<MyClass>();
std::shared_ptr<MyClass> instance2 =
std::make_shared<MyClass>();
instance1->another_instance = instance2;
instance2->another_instance = instance1;
return 0;
}
// 这段代码创建了两个MyClass对象,并使它们相互引用。这种做法的弊端在于,两个对象的引用计数永远无法降为0,因为它们相互引用。因此,这会导致内存泄漏,直到程序结束。要避免这种情况,应该避免使用shared_ptr相互引用,或者使用weak_ptr来引用。
使用场景:
#include
#include
void my_deleter(int* p) {
std::cout << "Deleting memory at " << p << std::endl;
delete p;
}
int main() {
std::shared_ptr<int> p(new int(10), my_deleter);
// 使用 reset 函数传递删除器
p.reset(new int(20), my_deleter);
return 0;
}
/*
通过构造函数和 reset 函数分别传递了一个自定义删除器 my_deleter,当 shared_ptr 对象释放资源时,my_deleter 函数会被调用,输出一条消息表示正在删除内存。
*/
一种多线程安全的指针,一般用于需要访问shared_ptr的场景。不能操作资源。
weak_ptr指针是一种用于解决 shared_ptr 循环引用问题的智能指针,它不能直接使用对象,必须转化为 shared_ptr 对象后进行使用。
它指向由shared_ptr控制的对象,不会增加引用计数,也不会阻止被指向对象的销毁,但它本身不控制该对象。当对象被销毁后,weak_ptr会自动失效。
一种独享所有权的指针;拥有“独占”这一特性,即在指针对象的生命周期内,它是指向唯一的对象的,其他的独占指针或普通指针都不能指向这个对象。
它不允许其他的智能指针共享其内部的指针,可以通过它的构造函数初始化一个独占智能指针对象,但是不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr。
当unique_ptr指针被销毁时,它所管理的对象也会随之被销毁,从而保证了对象的唯一性。unique_ptr可以通过移动语义来实现指针的所有权的转让,即将一个unique_ptr的所有权转移给另一个unique_ptr对象。
使用unique_ptr要注意的是不要将同一对象交给不同的unique_ptr对象控制,避免重复delete的问题。
使用 unique_ptr 可以防止多个指针同时使用同一块内存,从而避免内存泄漏的问题。
使用unique_ptr时需要注意以下几点: