【问题标题】:Chaining calls together with shared pointers将调用与共享指针链接在一起
【发布时间】:2013-03-01 09:44:25
【问题描述】:

这可能是一个“最佳实践”问题,但我想确保我以正确的方式解决这个问题。

我有以下课程:

typedef boost::shared_ptr<MyClass> MyClassPtr;

class MyClass final : public boost::enable_shared_from_this<MyClass> {
public:
    /* ctors/dtor ommitted */

    MyClassPtr method1() {
         // does something
         return shared_from_this();
    };

    MyClassPtr method2() {
         // does something
         return shared_from_this();
    };

}; // eo class MyClass

这是因为我想轻松地将调用链接在一起:

MyClassPtr ptr(myClassFactory.createMyClass());

ptr->method1()->method2()->methodX();  // etc...

这是shared_from_this() 成语的合适用法吗?有没有我不知道的问题,或者有更好的方法吗?

【问题讨论】:

  • 为什么要继续复制构造共享指针(这相当昂贵,因为它需要原子增量)?如果这是唯一目的,为什么不返回裸指针?
  • @DavidSchwartz,这确实是我的问题。虽然唯一的目的确实是将调用链接在一起 - 我担心会突然返回一个裸指针。因此我的问题:) 这是“气味”吗?
  • 为什么不使用引用。您正在尝试做的事情听起来像是 fluent interfaces 的实现。
  • 一个更常见的链接习惯用语,它没有裸指针气味(如果你认为它是一个)将返回对*this的引用,这样你就有@987654326 @ 或 obj.method1().method2().methodX();.
  • 有什么特别的原因不只是实现operator-&gt; 来完成链接吗?

标签: c++ boost shared-ptr


【解决方案1】:

函数调用链通常是通过返回对对象的引用来完成的:

MyClass& method1() {
     // does something
     return *this;
};

使用shared_ptr 表示您希望MyClass 的唯一用途是将其包裹在shared_ptr 中。事实上,如果有人创建一个具有自动存储持续时间的MyClass 并调用您的方法之一,您将会遇到问题,因为当返回的shared_ptr 被销毁时,它会尝试delete 您的对象。当然,你不能delete一个具有自动存储时长的对象。

我通常认为enable_shared_from_this 应该只在你的类提供一个静态工厂函数来为自己生成shared_ptrs 并且它的构造函数是私有的时使用。这可以防止任何人创建具有自动存储期限的此类对象。

尽管如此,如果他们要进行函数链接,大多数人会期望对对象的引用。那么至少他们可以这样做:

MyClass foo;
foo.method1().method2();

代替:

MyClass foo;
foo.method()->method2();

【讨论】:

  • 我同意。就是这样,正如我在 cmets 中提到的,但它看起来更像:MyClassPtr foo; foo-&gt;method().method2(),并且我希望运算符是统一的(例如所有 -&gt;)以避免混淆。
  • 但是,我认为你是对的——经过深思熟虑。如果一个人希望链接使用引用工作,那么也许第一个尊重可以忽略,因为其余的将遵循套件。
  • 你总是可以使用(*ptr).method1().method2();来避免最初的-&gt;
  • @Moo-Juice 如果他们有一个指向你的对象的指针,那么他们就会明白他们需要使用-&gt; 来访问一个成员。默认情况下,人们应该考虑对象而不是指针。毕竟,他们可以做(*foo).method1().method2();
猜你喜欢
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 2013-10-25
  • 2013-06-26
  • 2017-08-22
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多