【问题标题】:C++11 way of storing a polymorphic object in a classC++11在类中存储多态对象的方法
【发布时间】:2016-10-19 15:40:17
【问题描述】:

在 C++11 之前,我会实现一个类 Foo,其中包含基类 Bar 的多态对象:

struct Foo {

  Bar* m_b;

  Foo(Bar* b) : m_b(b) {}

}; 

按照 Scott Meyer 关于原始指针不好的建议,我想以 C++11 的方式实现 Foo,但我不知道这会是什么样子。

我开始写它像

struct Foo {

  std::unique_ptr<Bar> m_b;

  Foo(std::unique_ptr<Bar> b) : m_b(std::move(b)) {}

};

但这有一个缺点,b 必须动态分配。

那么 C++11 实现包含多态对象的类的方法是什么?

【问题讨论】:

  • Foo 实例是否拥有其m_b 指向的Bar 的所有权?
  • @user2357112 是的,(虽然我也有兴趣处理 No case)
  • 您为什么认为Bar 是多态的这一事实与此相关?
  • @user695652:如果Foo 拥有其Bar 的所有权,您的原始代码将泄露Bar 对象。你会怎么处理呢?
  • @user695652:智能指针用于表达所有权。在使用智能指针的代码库中,裸指针表示缺乏所有权。

标签: c++11 polymorphism smart-pointers


【解决方案1】:

智能指针优于原始指针的论点是基于所有权的。

资源的所有权应该从类型系统中明确,因为它很容易出错,而仅仅阅读代码就很难理解。通过将其嵌入类型系统中,您可以从对象的类型中判断出是什么决定了对象的生命周期。

C++11 之前的代码要么不拥有Bar(它不对其生命周期负责),要么你的代码泄露了。

后 C++11 代码拥有 Bar 并负责其生命周期。

如果您希望Foo 基于可能复杂的运行时逻辑有条件地拥有Bar 并且有时没有,那么std 智能指针可能不是一个好主意。

想象一下,在汽车安全规则之前,您有一辆汽车。它有一个按钮,可以将乘客从车上弹出。这很有趣,只要您不按下按钮,就很安全。

现在汽车安全规则已经出台,您听说遵守这些规则“更好”。您来到汽车安全问答环节,询问如何设置一个按钮,将您的乘客从汽车中弹出并遵守这些汽车安全规则。他们似乎不允许乘客弹射。即使您在按钮上盖上盖子,也有一些关于“如果汽车发生事故并且按钮执行不正确怎么办”以及生命和肢体等内容。

如何在我的车上安装弹射座椅,同时获得 5 星安全评级?

智能指针使所有权清晰。如果您混淆了所有权,那么您必须澄清它才能使用智能指针。

有些情况可以证明复杂的所有权和生命周期语义是合理的。这些很少而且相差甚远,通过默认使用智能指针,我们可以避免生命周期的复杂性而不必每次都验证它

struct Foo {
  std::unique_ptr<Bar> m_b;

  Foo(std::unique_ptr<Bar> b) : m_b(std::move(b)) {}
};

这是一个更好的接口,因为Foo 的ctor 清楚地表明它拥有所有权。获取原始指针,然后将其包装在智能指针中,会使接口变得不清晰。

【讨论】:

    猜你喜欢
    • 2013-08-13
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多