Как реализовать слабую ссылку на объект в конструкторе, используя boost :: weak_ptr? - PullRequest
0 голосов
/ 10 апреля 2019

Как создать boost :: weak_ptr для выходящего объекта в C ++ внутри конструктора?

Вот что у меня есть, но это не работает, потому что конструктор общего указателя неправильный.Дело в том, что я не хочу делать новую задачу.Я хочу использовать задачу, которая требуется для создания 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 ]

1 голос
/ 10 апреля 2019

Большая часть этой функциональности включена в стандарт C ++. Если вы не можете использовать такую ​​последнюю версию, тогда библиотеки наддува почти идентичны, и вы можете заменить std:: на boost:: здесь.

Для создания shared_ptr или weak_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

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10 * * * * * * * * * * * * * * * * * * * * * * * *). *1010* Добавит небольшой размер к вашему типу, но затем make_shared добавит к типу, который его не использует, поэтому, если это важно, или часто для простоты, есть unique_ptr (C + +11) это больше похоже на необработанный указатель.

Обычно все же не имеет смысла пытаться создать объект из выделенного стека объекта, так как shared_ptr не будет препятствовать его удалению, как обычные локальные переменные, и фактически может вызвать двойное удаление. Вы можете сделать несколько трюков, например, «удалить» для второй проблемы.

В случае Foo *ptr вам также необходимо убедиться, что некоторые другие shared_ptr для него все еще существуют, иначе ptr, возможно, уже был удален.

0 голосов
/ 23 апреля 2019

Таким образом, ответ таков: нельзя создать объект со слабым указателем.Вот пример, который вы можете использовать для реализации слабых ссылок между объектами.

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