std::make_unique 是 C++14 引入的辅助函数,用于安全、简洁地创建 std::unique_ptr 对象,避免手动使用 new 导致的内存泄漏和异常不安全问题。它通过单一表达式完成对象构造和智能指针初始化,确保异常安全,同时提升代码可读性。对于单个对象和数组类型均支持,但数组仅能接受大小参数并进行默认初始化;不支持自定义删除器,需直接使用 unique_ptr 构造函数处理特殊资源释放。在现代 C++ 中,std::make_unique 与 std::unique_ptr 共同实现 RAII 原则,确保资源的自动管理和程序的健壮性,是动态内存管理的推荐方式。

std::make_unique
std::unique_ptr
new
要使用
std::make_unique
unique_ptr
make_unique
基本用法示例:
#include <memory>
#include <iostream>
#include <string>
class MyObject {
public:
MyObject() {
std::cout << "MyObject default constructor called." << std::endl;
}
MyObject(int id, const std::string& name) : id_(id), name_(name) {
std::cout << "MyObject constructor with args called: ID=" << id_ << ", Name=" << name_ << std::endl;
}
~MyObject() {
std::cout << "MyObject destructor called. ID=" << id_ << std::endl;
}
void greet() const {
std::cout << "Hello from MyObject! ID=" << id_ << ", Name=" << name_ << std::endl;
}
private:
int id_ = 0;
std::string name_ = "Default";
};
int main() {
// 1. 创建一个不带参数的MyObject
// 这等价于 std::unique_ptr<MyObject>(new MyObject());
std::unique_ptr<MyObject> obj1 = std::make_unique<MyObject>();
obj1->greet();
std::cout << "--------------------" << std::endl;
// 2. 创建一个带参数的MyObject
// 这等价于 std::unique_ptr<MyObject>(new MyObject(101, "Alice"));
std::unique_ptr<MyObject> obj2 = std::make_unique<MyObject>(101, "Alice");
obj2->greet();
std::cout << "--------------------" << std::endl;
// 3. 创建一个MyObject数组
// 这等价于 std::unique_ptr<MyObject[]>(new MyObject[3]);
// 数组元素会被默认初始化或值初始化
std::unique_ptr<MyObject[]> objArray = std::make_unique<MyObject[]>(3);
// 访问数组元素,例如:objArray[0].greet();
// 注意:对于数组,make_unique只接受大小参数,不接受单个元素的构造函数参数。
// 如果需要自定义数组元素的构造,可能需要手动循环或考虑std::vector。
std::cout << "Exiting main scope." << std::endl;
// 当unique_ptr超出作用域时,它所管理的内存会被自动释放。
return 0;
}这段代码清晰地展示了
make_unique
unique_ptr
new
delete
unique_ptr
立即学习“C++免费学习笔记(深入)”;
std::make_unique
new
unique_ptr
这其实是一个非常关键的问题,不仅仅是代码看起来更简洁那么简单,背后还有深层次的设计考量和实际益处。从我个人的经验来看,坚持使用
make_unique
首先,最核心的原因是异常安全性。考虑这样一个场景:
void process(std::unique_ptr<Resource> res, AnotherObject obj); // 假设AnotherObject构造函数可能抛异常 // 潜在问题代码: process(std::unique_ptr<Resource>(new Resource()), AnotherObject());
在
process
new Resource()
AnotherObject()
std::unique_ptr<Resource>
new Resource()
AnotherObject()
std::unique_ptr<Resource>
new Resource()
Resource
而使用
std::make_unique
process(std::make_unique<Resource>(), AnotherObject());
std::make_unique<Resource>()
unique_ptr
Resource
unique_ptr
AnotherObject()
unique_ptr
Resource
process
unique_ptr
其次,是代码的简洁性和可读性。对比
std::unique_ptr<MyObject>(new MyObject(arg1, arg2))
std::make_unique<MyObject>(arg1, arg2)
最后,虽然对
unique_ptr
shared_ptr
make_unique
unique_ptr
make_unique
unique_ptr
new
std::make_unique
是的,
std::make_unique
处理数组:
std::make_unique
unique_ptr
当你需要创建数组时,类型参数应该是一个“数组类型”,并且需要提供数组的大小:
std::unique_ptr<int[]> intArray = std::make_unique<int[]>(10); // 创建一个包含10个int的数组
for (int i = 0; i < 10; ++i) {
intArray[i] = i * 2;
}
// 当 intArray 超出作用域时,会自动调用 delete[] 释放内存这里需要注意的关键点是:
T[]
T
make_unique<T[]>
make_unique
std::vector
unique_ptr<T[]>
delete[]
std::unique_ptr<T[]>
delete[]
delete
delete[]
处理自定义删除器:
这是
std::make_unique
std::make_unique
unique_ptr
new
delete
delete[]
如果你需要使用自定义删除器,你必须直接调用
std::unique_ptr
例如,管理一个
FILE*
#include <cstdio> // For FILE, fopen, fclose
// 自定义删除器,用于关闭文件
struct FileCloser {
void operator()(FILE* filePtr) const {
if (filePtr) {
std::cout << "Closing file..." << std::endl;
fclose(filePtr);
}
}
};
int main() {
// 错误:make_unique 不支持自定义删除器
// std::unique_ptr<FILE, FileCloser> pFile = std::make_unique<FILE>(fopen("test.txt", "w"));
// 正确:直接使用 unique_ptr 构造函数
// 模板参数是 <类型, 删除器类型>
// 构造函数参数是 (原始指针, 删除器对象)
std::unique_ptr<FILE, FileCloser> pFile(fopen("test.txt", "w"), FileCloser());
if (pFile) {
fprintf(pFile.get(), "Hello from unique_ptr!\n");
std::cout << "File opened and written to." << std::endl;
} else {
std::cerr << "Failed to open file." << std::endl;
}
// 当 pFile 超出作用域时,FileCloser::operator() 会被调用
std::cout << "Exiting main scope for custom deleter example." << std::endl;
return 0;
}在这个例子中,
FileCloser
FILE*
std::unique_ptr<FILE, FileCloser>(...)
unique_ptr
FileCloser
make_unique
unique_ptr
unique_ptr
make_unique
在现代 C++ 开发中,
unique_ptr
make_unique
new
delete
它们的核心作用在于实现 RAII (Resource Acquisition Is Initialization) 原则。
unique_ptr
unique_ptr
new
unique_ptr
new
delete
unique_ptr
unique_ptr
unique_ptr
unique_ptr
std::move
unique_ptr
unique_ptr
delete
unique_ptr
make_unique
unique_ptr
unique_ptr<Impl>
make_unique
unique_ptr
unique_ptr
unique_ptr
make_unique
unique_ptr
new
总而言之,
unique_ptr
make_unique
以上就是C++如何使用make_unique创建unique_ptr对象的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号