【问题标题】:C++ 11 Smart Pointer usageC++ 11 智能指针用法
【发布时间】:2014-11-22 11:45:05
【问题描述】:

我有一个关于 c++ 11 中智能指针的问题。我已经开始研究 C++ 11(我通常使用 c# 编程)并阅读了一些关于智能指针的内容。现在我有一个问题,智能指针是否完全取代了“旧”样式的指针,我应该一直使用它们吗?

unique_ptr 似乎解决了 C++ 中内存管理的所有问题,还是我错了?

例如:

std::unique_ptr<GameManager> game (new GameManager());

game->Start();

似乎比:

auto *game2 = new GameManager();

game2->Start();

delete game2;

谢谢你,我有点困惑!

【问题讨论】:

  • 在没有所有权问题的情况下,您不应该使用它们。例如,如果某个东西拥有游戏管理器,而其他东西想要使用它(例如多态)并且对其所有权或生命周期没有发言权,那么您可以考虑将原始指针传递给它。
  • 谢谢,现在更清楚了
  • “解决所有问题” - 不。不过,它解决了很多问题。
  • 尽管如此,在 C++ 中根本不需要使用动态内存。与 C# 不同,C++ 允许您在堆栈上创建类实例,并且它们在其包含范围退出时被销毁。

标签: c++ pointers c++11 smart-pointers unique-ptr


【解决方案1】:

对于所示的用法,虽然unique_ptr 比原始指针更好,因为它表示分配资源的所有权,但您可能根本不应该使用任何类型的指针。相反,只需声明一个本地:

GameManager game;
game.Start();

如果必须将所有权转让给其他东西,这可能还不够,而 unique_ptr 的所有权可以很容易地转移。

【讨论】:

  • 我提出了这个答案,因为它指出 - 正如上面的另一条评论 - 通过将对象放在堆栈上,一个人可以在没有任何指针的情况下很好地生活在 C++ 中。
  • 这确实应该是公认的答案。当前接受的答案听起来像是堆分配本地范围的实例比堆栈分配更可取,这很少是真的。
【解决方案2】:

回答您的问题:是的,它们确实解决了内存管​​理问题。

尽可能多地使用它们被认为是好的风格。

它们消除了许多可能的编程错误,并降低了使用指针创建正确代码的难度。

为了走得更远,改变也被认为是好的

std::unique_ptr<GameManager> game (new GameManager());

收件人:

std::unique_ptr<GameManager> game (std::make_unique<GameManager>());

【讨论】:

  • 感谢您的快速回答,但是这个对 make_unique 的回答是什么:stackoverflow.com/a/9657991
  • c++14 现已正式发布,Visual Studio 在新标准出台之前就提供了 make_unique
  • 我使用的风格是auto game = std::make_unique();
  • 是的 - 如果类型被重命名,它只是不那么冗长和更少的变化
  • @BendEg 不,你使用智能指针,auto 只是从初始化表达式推断类型unique_ptr。这种风格似乎也更具可读性。
【解决方案3】:

不,不要完全替换所有原始指针。

使用智能指针(unique_ptr、shared_ptr)只对那些拥有和管理指针内存的指针真正有用。但是,如果函数将指针作为参数,那么您就不想转移所有权。该函数只需要访问指针。

void ShowCredits(GameManager* game)   // Just use game, don't take ownership.
{                                     // A raw pointer here is good.
   // ...
}

void main()
{
    auto game = make_unique<GameManager>(); // game owns the GameManager.
    game->Start();
    ShowCredits(game.get());
}

附:如果 ShowCredits 依赖于游戏始终有效(即它不能有选择地具有 nullptr 值),那么在这种情况下,使用 GameManager& 类型的参数实际上可能会更好。

【讨论】:

  • 通过引用传递而不是指针传递ShowCredits(GameManager&amp; game);
  • main 应该返回 int
【解决方案4】:

除了unique_ptr的单一所有权外,还有一些情况是共享的,或者难以定义所有权。在这些情况下,shared_ptr 提供引用计数,最后一个所有者将删除该引用。

shared_ptr 可能涉及复杂引用循环的情况下,该标准还提供了weak_ptr

所有这些都取代了旧的auto_ptr

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 2015-10-30
    • 2021-12-26
    • 2019-06-30
    相关资源
    最近更新 更多