【问题标题】:Is it possible in C++ to have a method in the superclass that when called by each subclass returns a shared_ptr to that subclass?在 C++ 中是否有可能在超类中有一个方法,当每个子类调用该方法时,该方法会向该子类返回一个 shared_ptr ?
【发布时间】:2020-09-21 06:38:20
【问题描述】:

我希望超类的所有孩子都执行类似的操作。所以我想我可以在超类中有一个方法来做到这一点。该操作需要将自身的副本(或 shared_ptr 发送到)作为方法的参数。但是我不知道这样的事情是否可行,如果可以,应该怎么做。

为了澄清我的问题,请考虑以下示例。我希望打印输出是“孩子”和“父母”。当前代码打印出“父母”和“父母”。当然,这是预期的,因为我将复制 *this 作为 make_shared 中的 Parent 类型返回。

问题是我是否可以获得预期的行为。请注意,在实际情况下,有很多孩子,因此在每个孩子中实现函数 getPtr() 并不容易。

感谢您的帮助。

class Parent
{
public:
  std::shared_ptr<Parent> getPtr() { return std::make_shared<Parent>(*this); } // I tried make_shared<decltype(*this)> also, but the code does not compile.

  virtual void printName() const { std::cout << "Parent\n"; }
};

class Child1 : public Parent {
  void printName() const override { std::cout << "Child\n"; }
};

int main() {
  Child1 c;
  auto cPtr = c.getPtr();
  cPtr->printName();       // I want this to print "Child", but it prints "Parent" (as expected)

  Parent p;
  auto pPtr = p.getPtr();
  pPtr->printName();
}

【问题讨论】:

  • virtual std::shared_ptr&lt;Parent&gt; getPtr() const { return std::make_shared&lt;Parent&gt;(*this); } 在 Parent 类中,std::shared_ptr&lt;Parent&gt; getPtr() const override { return std::make_shared&lt;Child1&gt;(*this); } 在 Child1 类中。

标签: c++ subclass superclass virtual-functions


【解决方案1】:

不完全清楚你在做什么,但你肯定想从std::enable_shared_from_this 派生你的Parent

这会给你一个成员函数shared_from_this()(这或多或少是你想通过getPtr()实现的)。

但是,必须强调您的Parent 对象本身必须由std::shared_ptr 管理。即,这仅在且仅当

std::shared_ptr<Parent> p = std::make_shared<Parent>();

然后你可以使用p-&gt;shared_from_this()给你一个共享指针。

【讨论】:

  • 对我来说重要的实际上是获取 shared_ptr 或可以转换为 Child 的 shared_ptr。您提出的方法可以做到这一点吗?
  • 是的,您必须使用std::dynamic_pointer_cast 将您的Parent 指针向上转换为Child
  • 我还要注意,如果没有std::enable_shared_from_this,就不能有一个可移植的getPtr() 实现,因为std::shared_ptr 包含指针部分和控制块部分。如果不启用 shared_ptr,您将试图凭空来操纵控制块。
  • 在给定的 OP 代码中,使用 std::enable_shared_from_this 是不必要的。
  • @Eljay 我明白了,但我想他的意图是返回一个 shared_ptr 而不复制构造 *this,评论似乎表明了这一点。
猜你喜欢
  • 2021-09-21
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 2020-09-14
  • 1970-01-01
  • 2018-06-06
相关资源
最近更新 更多