【C语言教程】C++ 智能指针最佳实践:从 new 到 std::make_unique 的演进

零 C语言教程评论110字数 1631阅读5分26秒阅读模式

 

以下内容为本人的烂笔头,如需要转载,请全文无改动地复制粘贴,原文链接 微信公众号「ENG八戒」mp.weixin.qq.com/s/imoYFpDo2…文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/15555.html

【C语言教程】C++ 智能指针最佳实践:从 new 到 std::make_unique 的演进文章源自灵鲨社区-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 其实就是一种工厂函数(应用了工厂设计模式的函数),直接管理资源,避免了额外的指针操作,在某些场景下可能带来性能上的些小提升。

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/cyyjc/15555.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论