【问题标题】:Returning unique_ptr in Factory在工厂中返回 unique_ptr
【发布时间】:2015-12-21 13:59:04
【问题描述】:

也许这是一个简单的问题,因为我还是 C++ 新手。我想使用某种工厂来封装我的应用程序中的日志记录。这个想法是只有工厂知道哪个具体类将处理函数调用。应用程序将始终调用基本日志记录类的抽象接口。

工厂方法应该是这样的:

std::unique_ptr<AbstractLoggingClass> Factory::getDefaultLogger(const std::string& param){
    return new ConcreteLoggingClass(param);
}

ConcreteLoggingClassAbstractLoggingClass 的子类。

但我收到以下错误:

Error: could not convert '(operator new(64ul), (<statement>,
((ConcreteLoggingClass*)<anonymous>)))' from 'ConcreteLoggingClass*'
to 'std::unique_ptr<AbstractLoggingClass>'

我的问题是我不知道如何实例化ConcreteLoggingClass 并将unique_ptr 返回到AbstractLoggingClass

我已经找到this post,但我仍然没有找到解决方案。

【问题讨论】:

  • 为什么?请您解释一下,而不是默默地投反对票。
  • 我仍然没有得到反对票。但感谢其他所有人提供有用的答案。

标签: c++ factory-pattern unique-ptr


【解决方案1】:

您想要的std::unique_ptr 构造函数是explicit,因此您需要...嗯...明确说明。试试

return std::unique_ptr<AbstractLoggingClass>(new ConcreteLoggingClass(param));

【讨论】:

  • 完成了这项工作。非常感谢!
  • 就 C++ 而言是正确的答案,但我不知道为什么 C++ 会做出这个决定。 ConcreteLoggingClassAbstractLoggingClass,使用 Liskov 替换原则意义上的“is a”。
【解决方案2】:

如果你可以使用 C++14,你应该使用std::make_unique:

return std::make_unique<ConcreteLoggingClass>( param );

否则显式创建std::unique_ptr:

return std::unique_ptr<AbstractLoggingClass>{ new ConcreteLoggingClass{param}};

【讨论】:

  • 我还没有 C++14。但我已经知道 make_unique。这看起来很方便。
【解决方案3】:

std::unique_ptr&lt;T&gt; 的构造函数是explicit。它不会从指针隐式转换,因为这样做意味着指针被静默删除。

您可以返回一个std::unique_ptr&lt;T&gt; 显式构造它,例如:

return std::unique_ptr<AbstractLoggingClass>(new ConcreteLoggingClass(param));

【讨论】:

    【解决方案4】:

    您无法将指针转换为unique_ptr,您必须创建它:

    std::unique_ptr<AbstractLoggingClass> Factory::getDefaultLogger(const std::string& param){
        return std::unique_ptr<AbstractLoggingClass>(new ConcreteLoggingClass(param));
    }
    

    【讨论】:

      【解决方案5】:

      如果你有 c++14 或更高版本:

      std::unique_ptr<AbstractLoggingClass> 
      Factory::getDefaultLogger(const std::string& param)
      {
          return std::make_unique<ConcreteLoggingClass>(param);
      }
      

      【讨论】:

      • 我目前没有可用的 c++14。不过谢谢你提出这个建议,也许我以后可以用这个。
      猜你喜欢
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-01
      • 2023-02-02
      • 2017-05-10
      • 2012-08-13
      相关资源
      最近更新 更多