shared_ptr和make_shared区别
时间: 2023-08-05 08:09:19 浏览: 50
shared_ptr和make_shared是C++中用于管理动态分配对象的智能指针。
1. shared_ptr:
- shared_ptr是一个类模板,用于管理动态分配对象的引用计数。
- shared_ptr可以指向任意动态分配的对象,并且可以共享所有权。
- 通过复制shared_ptr,引用计数会增加,当引用计数为0时,会自动释放关联的对象。
- shared_ptr需要额外的内存来存储引用计数,可能会导致一定的空间开销。
2. make_shared:
- make_shared是一个函数模板,用于直接创建并初始化shared_ptr。
- make_shared可以通过传递参数来创建对象,并将返回的shared_ptr指向该对象。
- make_shared在内存中一次性分配了用于存储对象和引用计数的内存块,可以减少空间开销。
- make_shared可以避免了显式使用new操作符来分配内存。
区别:
- 内存分配方式:shared_ptr使用单独的内存块存储引用计数,而make_shared在同一内存块中同时存储对象和引用计数。
- 性能和空间开销:make_shared通常比shared_ptr更高效,因为它只需要一次内存分配,并且可以减少空间开销。
- 使用场景:一般情况下,推荐使用make_shared,除非有特殊需求,如自定义内存分配器或需要显式控制资源释放的情况下,才使用shared_ptr。
相关问题
shared_ptr 和 unique_ptr 的区别
shared_ptr 和 unique_ptr 是C++中的智能指针,用于管理动态分配的内存。它们之间的区别如下:
1. 所有权:shared_ptr 允许多个智能指针共享同一个对象,而 unique_ptr 则独占所指向的对象。当最后一个 shared_ptr 被销毁时,它所指向的对象才会被销毁;而当 unique_ptr 被销毁时,它所指向的对象立即被销毁。
2. 拷贝和赋值:shared_ptr 可以进行拷贝和赋值操作,每次拷贝会增加对象的引用计数;unique_ptr 则禁止拷贝和赋值操作,只能通过移动语义来转移所有权。
3. 内存开销:shared_ptr 需要维护一个引用计数,以跟踪对象的引用数量,从而决定何时销毁对象;unique_ptr 不需要引用计数,因此内存开销更小。
4. 空指针检查:shared_ptr 可以通过检查是否为空来判断是否指向有效对象;unique_ptr 也可以通过检查是否为空,但更常用的是使用 bool 运算符来判断是否指向有效对象。
5. 自定义删除器:shared_ptr 允许指定自定义的删除器函数,用于在对象销毁时执行特定的操作;unique_ptr 也允许指定自定义的删除器函数,但是删除器函数的类型是在编译时确定的。
下面是一个示例程序,演示了 shared_ptr 和 unique_ptr 的使用:
```cpp
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() {
std::cout << "MyClass constructor" << std::endl;
}
~MyClass() {
std::cout << "MyClass destructor" << std::endl;
}
};
int main() {
// 使用 shared_ptr
std::shared_ptr<MyClass> sharedPtr1 = std::make_shared<MyClass>();
std::shared_ptr<MyClass> sharedPtr2 = sharedPtr1;
// 使用 unique_ptr
std::unique_ptr<MyClass> uniquePtr1 = std::make_unique<MyClass>();
// std::unique_ptr<MyClass> uniquePtr2 = uniquePtr1; // 错误,禁止拷贝和赋值操作
return 0;
}
```
shared_ptr和weak_ptr 共用例程
shared_ptr和weak_ptr是C++中的智能指针,用于管理动态分配的内存资源,避免内存泄漏和悬空指针的问题。
1. shared_ptr:
shared_ptr是一种引用计数智能指针,可以跟踪有多少个shared_ptr共享同一个对象。当最后一个shared_ptr离开作用域或被显式释放时,它会自动删除所管理的对象。shared_ptr的特点包括:
- 可以通过make_shared函数创建,也可以通过new关键字和构造函数创建。
- 可以通过shared_ptr的拷贝构造函数和赋值运算符进行拷贝和赋值,引用计数会增加。
- 可以使用use_count()函数获取当前有多少个shared_ptr共享同一个对象。
- 可以使用unique()函数判断当前是否只有一个shared_ptr指向对象。
- 可以使用reset()函数显式释放shared_ptr所管理的对象。
2. weak_ptr:
weak_ptr是一种弱引用智能指针,它可以解决shared_ptr的循环引用问题。weak_ptr可以与shared_ptr共享同一个对象,但不会增加引用计数。当最后一个shared_ptr离开作用域或被显式释放时,即使还有weak_ptr指向对象,对象也会被销毁。weak_ptr的特点包括:
- 不能直接通过new关键字和构造函数创建,只能通过shared_ptr的weak_ptr构造函数或lock()函数创建。
- 可以使用expired()函数判断所指向的对象是否已经被销毁。
- 可以使用lock()函数获取一个shared_ptr,如果对象已经被销毁,则返回一个空的shared_ptr。