Search code examples
c++shared-ptr

How to implement a weak reference to an object in a constructor using boost::weak_ptr?


How does one create a boost::weak_ptr to an exiting object in C++ inside a constructor?

Here's what I've got but it doesn't work because the shared pointer constructor is wrong. The thing is i don't want to make a new task. I want to use the task that is required to make a TestCallback but i only want a weak reference to the TestTask because the TestTask owns the TestCallback and if it goes away so should the TestCallback.

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

//Constructor

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

//Ideal Call Site

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

Solution

  • So the answer is that one cannot instantiate an object with a weak pointer. Here's an example you can use to implement weak references between objects.

    #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;
    }