【问题标题】:Conditional construction with shared_ptr?使用 shared_ptr 进行条件构造?
【发布时间】:2012-04-19 21:24:50
【问题描述】:

我有:

Command *command;

if(commandType == "Start")
{
  command = new StartCommand();
}
else if (commandType == "Stop")
{
  command = new StopCommand();
}

现在假设我想让command 成为一个shared_ptr,我该如何翻译上面的代码来使用一个shared_ptr?

【问题讨论】:

  • shared_ptr<Command> 替换Command*? (最好是new XXXCommand()make_shared<XXXCommand>()。)
  • std::shared_ptr<Command> command;,然后在分配的时候,做command.reset(new StartCommand)(或者另外一个)?
  • @birryree:谢谢,我想这是我正在寻找的重置功能。

标签: c++ constructor shared-ptr


【解决方案1】:

如果您想正确初始化变量,请跳过明显的步骤,例如如果是const,你可以这样做

std::shared_ptr<Command> factoryCommand(std::string const& commandType) {
  if(commandType == "Start")
    return std::make_shared<StartCommand>();
  if(commandType == "Stop")
    return std::make_shared<StopCommand>();
  return std::shared_ptr<Command>(nullptr);
}

std::shared_ptr<Command> const command {factoryCommand(commandType)};

正如 cmets 中所指出的,您还可以违反 C++ 的 RAII 准则并单独定义和初始化。不过,我仍然更喜欢使用std::shared_ptr&lt;Command&gt;::operator= 而不是std::shared_ptr&lt;Command&gt;::reset,因为它更直观,并且不会诱使您使用new 做一些您永远不会使用delete 的事情。

因此,例如,对于 "Start" 分支,它看起来像这样:

std::shared_ptr<Command> command;
//...
// I would flag this in the review process as "you're doing it wrong"
command.reset(new StartCommand());
// This is what you should do if you *have* to separate definition and initialisation:
command = std::make_shared<StartCommand>();

【讨论】:

  • +1 或者(更糟糕,只是为了完成):factoryCommand.reset( new XXXCommand() )
  • @DavidRodríguez-dribeas:实际上我最初是想用一个立即调用的 lambda 而不是 factoryCommand 来发布这个,但这无助于澄清实际问题,所以函数得到了一个名字。
  • 虽然我的示例建议这样做,但我不仅对工厂模式感兴趣。我想我的问题确实是如何分配给 shared_ptr。如果您将使用重置功能的示例添加到您的答案中,我会接受。
  • “违反 C++ 的 RAII 指南”这不会破坏 RAII。好吧,它打破了 RAII 首字母缩略词的字面意思,但 RAII 对清理比收购更感兴趣。它仍然是异常安全的,并且它仍然是堆栈绑定的,所以它仍然会被清理。那么它有什么不好呢?这与创建一个空的 vector 并稍后填充它没有什么不同。
  • @NicolBolas:那么,也许这是个人喜好。但我不明白为什么在定义附近只写入一次的变量应该是非常量的。
【解决方案2】:

一些非常简单的改变就可以完成这项工作:

shared_ptr<Command> command;

if(commandType == "Start")
{
  command = make_shared<StartCommand>();
}
else if (commandType == "Stop")
{
  command = make_shared<StopCommand>();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2021-06-01
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多