以下内容为本人的烂笔头,如需要转载,请全文无改动地复制粘贴,原文链接 微信公众号「ENG八戒」mp.weixin.qq.com/s/imoYFpDo2…文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
相比使用 new 直接创建对象指针再传入智能指针,使用模板函数 std::make_unique 创建智能指针 std::unique_ptr 对象有几点优势。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
先来看看使用 new 直接创建对象指针再传入智能指针的例子:文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
c
#include <memory>
#include <iostream>
class MyClass {
public:
MyClass(int value) : value_(value) {
std::cout << "construct obj" << std::endl;
}
~MyClass() {
std::cout << "destruct obj" << std::endl;
}
// ...
private:
int value_;
};
int main() {
MyClass* rawPtr = new MyClass(1);
// throw std::runtime_error("something wrong");
std::unique_ptr<MyClass> ptr(rawPtr);
// ...
return 0;
}
使用 new 操作符手动为 MyClass 对象分配内存,用返回的指针来初始化智能指针 std::unique_ptr 对象,这时 MyClass 对象的生命周期就完全交付给 std::unique_ptr 对象管理了,理论上 MyClass 对象内存指针已经不需要再维护。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
但是,一旦初始化智能指针对象完成之前发生了异常,如上代码(抛出异常信号 something wrong),如不处理,那么指针指向的内存就可能被泄漏,势必需要手动添加麻烦的异常处理负责善后:文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
arduino
int main() {
MyClass* rawPtr = nullptr;
try {
rawPtr = new MyClass(1);
// throw std::runtime_error("something wrong");
std::unique_ptr<MyClass> ptr(rawPtr);
// ...
} catch (const std::exception& e) {
if (rawPtr != nullptr) {
delete rawPtr;
rawPtr = nullptr;
}
std::cerr << e.what() << std::endl;
}
return 0;
}
与使用 new 直接创建对象指针再传入智能指针这种比较麻烦的方式相比,使用 std::make_unique 创建智能指针可以做到代码的简洁性、异常安全性和潜在的性能优化。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
下面看看,使用 std::make_unique 的例子:文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
c
#include <memory>
#include <iostream>
class MyClass {
public:
MyClass(int value) : value_(value) {
std::cout << "construct obj" << std::endl;
}
~MyClass() {
std::cout << "destruct obj" << std::endl;
}
// ...
private:
int value_;
};
int main() {
auto ptr = std::make_unique<MyClass>(1);
// ...
return 0;
}
上面代码中,只用了一行代码即完成 MyClass 对象的创建与智能指针的初始化,使得代码更为简洁易读。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
而且就算在创建对象和智能指针初始化之间发生异常,也不会留下未释放的内存,因为 std::make_unique 内部会自动处理异常,可见 std::make_unique 是异常安全的。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html
在构造复杂对象时,如果直接使用 new 可能导致多次内存分配,这对效率有影响。而 std::make_unique 其实就是一种工厂函数(应用了工厂设计模式的函数),直接管理资源,避免了额外的指针操作,在某些场景下可能带来性能上的些小提升。
评论