如何使用boost :: weak_ptr在构造函数中实现对对象的弱引用?

时间:2019-04-10 14:55:02

标签: c++ shared-ptr

如何在构造函数内的C ++中为现有对象创建boost :: weak_ptr?

这是我所拥有的,但是它不起作用,因为共享指针构造函数是错误的。问题是我不想做新任务。我想使用执行TestCallback所需的任务,但是我只想对TestTask进行弱引用,因为TestTask拥有TestCallback,如果它消失了,那么TestCallback也应该拥有。

class TestCallback {
  public:
    TestCallback(TestTask task);
    boost::weak_ptr<TestTask> testTask;
};

//构造函数

TestCallback(TestTask task) {
  boost::shared_ptr<DeleteStaticRouteTask> sharedTask(task);
  boost::weak_ptr<DeleteStaticRouteTask> weakTask(sharedTask);
  m_task = weakTask;
}

//理想的呼叫站点

TestTask testTask(DependencyA, DependencyB);
TestCallback testCallback(task);

2 个答案:

答案 0 :(得分:1)

大多数此功能已包含在C ++标准中。如果您不能使用这样的最新版本,则boost库几乎是相同的,您可以在此处将std::替换为boost::

要从原始指针创建shared_ptrweak_ptr,必须从enabled_shared_from_this派生,例如:

class Foo : public std::enabled_shared_from_this<Foo> // C++11
{
};
...
Foo *ptr = ...;
std::shared_ptr<Foo> a = foo->shared_from_this(); // C++11
std::weak_ptr<Foo> b = foo->weak_from_this(); // C++17

enabled_shared_from_this会为您的类型增加一些大小,但是make_shared也会为您的类型不使用它,因此,如果您担心或经常为了简单起见,可以使用{{ 1}}(C ++ 11),更像是原始指针。

尝试从堆栈分配的对象中创建一个对象通常还是没有意义的,因为shared_ptr不会像正常的局部变量一样防止其被删除,实际上可能会导致双重删除。您可以采取一些技巧,例如为第二个问题提供“无操作”删除器。

对于unique_ptr,您还需要确保其他Foo *ptr仍然存在,否则shared_ptr可能已经被删除。

答案 1 :(得分:0)

因此,答案是无法用弱指针实例化对象。这是一个示例,可用于在对象之间实现弱引用。

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>

class Callback;

class Task: public boost::enable_shared_from_this<Task>
{
  public:
    Task(Callback& callback)
      : m_callback(callback)
    {
      std::cout << "Task:: Constructor" << std::endl;
    }

    void delegateMethod() {
      std::cout << "Task: delegateMethod" << std::endl;
    }

  private:
    Callback& m_callback;
};


class Callback
{
  public:

    Callback(){
      std::cout << "Callback::Constructor" << std::endl;
    };

    //You have to set the delegate after Construction
    void delegate(const boost::weak_ptr<Task> task) {
      std::cout << "Callback:: void delegate(const boost::weak_ptr<Task> task) " << std::endl;
      this->m_delegate = task;
    }


    void delegateSomething() {
      std::cout << "Callback::delegateSomething()" << std::endl;
      boost::shared_ptr<Task> sharedDelegate = this->m_delegate.lock();
      std::cout << "sharedDelegate: " << sharedDelegate << std::endl;
      if (sharedDelegate) {
        // Use *shared_delegate
        std::cout << "Callback::delegateSomething() use delegate" << std::endl;
        sharedDelegate->delegateMethod();
      }
    }

    private:
     boost::weak_ptr<Task> m_delegate;
};

int main()
{
  std::cout << "main: Construct Callback" << std::endl;
  Callback callback;

  std::cout << "main: Construct Task" << std::endl;
  Task task(callback);

  std::cout << "main: Connect callback delegate" << std::endl;
  boost::shared_ptr<Task> sharedTask = boost::make_shared<Task>(task);
  boost::weak_ptr<Task> weakTask(sharedTask);
  callback.delegate(weakTask);
  callback.delegateSomething();

  return 0;
}