这个函数应该返回什么类型的对象?

Jos*_*son 8 c++ factory smart-pointers lifetime c++11

考虑这个课程:

class Widget
{
    Widget::Widget();
    bool initialize();
}
Run Code Online (Sandbox Code Playgroud)

A Widget具有以下特征:

  1. initialize() 必须调用才能完全构造
  2. initialize() 可能会失败
  3. initialize() 太贵了

鉴于此,我在工厂函数中封装创建,始终返回相同的Widget实例:

Widget* widget() {
    static auto w = new Widget;
    static auto initialized = false;

    if (!initialized) {
        if (!w->initialize()) {
            return nullptr;
        }
        initialized = true;
    }

    return w;
}
Run Code Online (Sandbox Code Playgroud)

返回类型应该widget()是什么?

特别是,我想以某种方式明确表示返回的生命周期Widget将超过任何调用者,但不会引用内部实现.

  1. 返回一个原始指针并添加一条注释,指出"返回的指针指向一个具有静态存储持续时间的对象,该对象在程序结束前不会被删除".这很简单,但不能自我记录.
  2. 回来一个std::shared_ptr<Widget>.这是自我记录的,但我不喜欢它会引入完全不必要的引用计数开销.
  3. std::unique_ptr<Widget>使用自动删除功能返回a .我认为如果调用者将其转换为#,则它与#2具有相同的感知问题shared_ptr.

Bar*_*rry 11

我投票支持:

boost::optional<Widget&> widget() {
    static Widget w; // no reason for this to be a pointer
    static bool initialized = false;

    if (!initialized) {
        if (!w.initialize()) {
            return boost::none;
        }
        initialized = true;
    }

    return w;
}
Run Code Online (Sandbox Code Playgroud)

这清楚地表明,主叫方不拥有Widget任何方式,有没有来电的担心delete-ing的Widget,而且很明显的呼叫是否成功.


And*_*tur 7

在这里做正确的事情不是原始指针吗?它已经表达了限制.它可能会失败(通过返回nullptr),并且由于它没有对指针做出任何承诺,因此调用者无法安全地将其删除.你得到一个原始指针,你不能假设你被允许做出有关指向对象生命周期的任何陈述.