【问题标题】:C++: Passing delegate to other object via std::weak_ptrC++:通过 std::weak_ptr 将委托传递给其他对象
【发布时间】:2023-03-26 23:46:02
【问题描述】:

我有两个类,例如 A 和 B。我想将 A 作为对 B 的引用。

class I
{
public:
    virtual void callback() = 0;
};

class B
{
public:
    B(I* callback) : _callback(callback) {}
private:
    I* _callback;
};

class A : public I
{
public:
    A() : _b(new B(this)) {}
private:
    B* _b;
};

我想:

  1. 摆脱裸指针(例如,借助 std::shared_ptr 和 std::weak_ptr)。
  2. 避免循环引用。

但是有一些问题:

  1. 如何在 A 类中创建弱指针?首先,我应该确定 A 的一个实例是由一些 shared_ptr 管理的。即使我很确定,我怎样才能找到这个 shared_ptr 实例?
  2. 一般来说,我如何确保我只通过共享指针使用某个类的实例?我可以尝试创建工厂方法并将构造函数设为私有,但这会导致错误:make_shared 需要公共构造函数。

提前致谢!

编辑:

问题的更详细解释:我有一个类 A。这个类想要将部分工作传递给类 B。所以我在 A 中有一个指向 B 的共享指针。我希望 B 异步执行此操作,当有一些进展或工作完成时,B 应该调用 A 的回调。所以 B 应该有 A 的引用。

class I
{
public:
    virtual void isDone() = 0;
};

class B
{
public:
    B(I* callback) : _callback(callback) //how do I take and store callback inside B???
    {
        //async invocation of run()
    }
private:
    weak_ptr<I> _callback;

    void run()
    {
        if(_callback.get())
        {
            _callback->isDone();
        }
    }
};

class A : public I
{
public:
    A() : _b(new B(this)) {} //how do I pass this to B???
private:
    shared_ptr<B> _b;

    virtual void isDone()
    {
        cout << "job is complete" << '\n';
    }
};

所以问题是:我如何将 A 传递给 B?我可以尝试通过裸指针或引用来做到这一点,但它是安全的,因为 B 不能保证这个引用的对象仍然存在(所有裸指针的常见问题)。所以我想传递一个弱指针,我的问题就是它。

【问题讨论】:

  • 在您的示例中没有看到任何std::weak_ptr??
  • @πάνταῥεῖ 这个例子是问题的根源。正确使用弱指针是问题的本质:)。
  • 通常它有助于解决 SO 问题,显示您尝试过的内容以及为什么它不起作用。
  • 在这种情况下,我会使用完全共享指针,而不是弱指针。如果您想允许对象超出范围然后处理这种情况,请使用 weak_ptr,但在这种情况下,您希望对象超出范围。由于您已经在使用共享指针,因此使用更多共享指针实例不会增加任何开销。
  • @MadScienceDreams 但是循环引用呢?如果 A 有一个指向 B 的共享指针,而 B 有一个指向 A 的共享指针?

标签: c++ c++11 delegates shared-ptr weak-ptr


【解决方案1】:

第一个问题可以用std::enable_shared_from_this 解决,它允许您从A 类中安全地创建一个共享指针实例。

第二个问题可以通过使用属于类A的静态工厂方法而不是像这样使用std::make_shared来解决:

static std::shared_ptr<A> create() {
    return std::shared_ptr<A>(new A());
}

然后,您可以将A 的构造函数设为私有。

【讨论】:

  • 非常感谢,克里斯蒂安!还有一个问题:将弱指针传递给其他类的常见做法是什么?我应该在哪里创建一个弱指针:在 A 内部(通过之前)还是在 B 内部(通过之后)?
  • 我通常在 B 中这样做。我从不传递弱 ptrs。尽管在方法签名中记录所有权语义有一些话要说。
  • (+1,虽然你应该提到工厂方法可能属于另一个朋友类,因为工厂模式是的)
猜你喜欢
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 2020-07-28
  • 2012-07-12
  • 2015-08-30
  • 2019-11-25
  • 1970-01-01
相关资源
最近更新 更多