c++ 之 make_shared
**C++ 中的 `make_shared`**
在 C++ 中,`std::shared_ptr` 是一种智能指针,它允许多个对象共享同一个原始指针。然而,在使用 `std::shared_ptr` 时,我们经常会遇到一个问题:如何创建一个 `std::shared_ptr` 的实例?这是 `make_shared` 函数的作用。
**什么是 `make_shared`**
`make_shared` 是 C++11 中引入的一种函数,它允许我们在不手动管理原始指针的情况下创建一个 `std::shared_ptr` 的实例。它的作用类似于 `new` 和 `delete` 的组合,但比它们更安全和高效。
**使用 `make_shared`**
要使用 `make_shared`,我们需要包含 `cpp#include <memory>
int main() {
// 使用 make_shared 创建一个 std::shared_ptr 的实例 auto ptr = std::make_shared<int>(5);
// 使用 ptr 进行操作 *ptr =10;
std::cout << "Value: " << *ptr << std::endl;
return0;
}
在上面的示例中,我们使用 `std::make_shared` 创建了一个 `std::shared_ptr
**如何实现 `make_shared`**
虽然我们可以直接使用 `std::make_shared` 函数,但了解它的内部实现也很有趣。让我们来看一下一个简单的实现:cpptemplate <typename T>
class shared_ptr {
public:
// ...
};
template <typename T>
shared_ptr<T> make_shared(T* ptr) {
return shared_ptr<T>(ptr);
}
在这个示例中,我们定义了一个 `shared_ptr` 类模板,并提供了一个 `make_shared` 函数,它接受一个原始指针作为参数,并返回一个 `shared_ptr` 的实例。
然而,这个实现有一个问题:它没有考虑到 `std::shared_ptr` 的内存管理机制。我们需要在 `make_shared` 中手动分配和释放内存,这会导致代码复杂度的增加。
**C++11 中的 `make_shared`**
在 C++11 中,`std::make_shared` 函数被定义为:cpptemplate <typename T>
shared_ptr<T> make_shared(T* ptr) {
return shared_ptr<T>(new T(*ptr));
}
这个实现看起来很简单,但它实际上是通过 `new` 来分配内存的。然而,这个过程有一个问题:如果 `T` 的构造函数抛出异常,原始指针将不会被释放。
**C++14 中的 `make_shared`**
在 C++14 中,`std::make_shared` 函数被定义为:cpptemplate <typename T>
shared_ptr<T> make_shared(T* ptr) {
return shared_ptr<T>(new T(*ptr), std::uninitialized_copy(ptr));
}
这个实现看起来比前一个版本更复杂,但它实际上是通过 `std::uninitialized_copy` 来分配内存的。这种方式可以避免异常抛出时原始指针未释放的问题。
**总结**
在 C++ 中,`make_shared` 函数允许我们创建一个 `std::shared_ptr` 的实例,而无需手动管理原始指针。在不同的 C++ 版本中,这个函数的实现有所不同,但它都提供了一个高效和安全的方式来使用智能指针。