Пустой слабый указатель в enable_shared_from_this - PullRequest
0 голосов
/ 12 мая 2019

После публичного наследования enable_shared_from_this и инициализации объекта класса при вызове другой функции этого класса я все еще вижу пустой слабый указатель enable_shared_from_this_class при отладке в Visual Studio.

Все существующие вопросы связаны счастное наследование от enable_shared_from_this или вызов слабого_from_this в конструкторе.Это не тот случай для меня.В настоящее время я использую c ++ catch Framework для тестирования этого сценария в отладчике Visual Studio.В функции Initialize я вижу, что слабый_птр этого объекта пуст.

заголовочный файл:


template <typename T>
class IInfo
public:
IInfo()
    {}
    virtual ~IInfo()
    {}
    virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T>) = 0;
};

template <typename T>
class Info : public IInfo<T>, public std::enable_shared_from_this<Info<T>>
{
public:
    Info() {}
    ~Info() {}
    virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T> callerContext) override
    {
        //Some code
        _callerContext = callerContext;
    }
private:
    std::weak_ptr<T> _callerContext;
};


class Env : public std::enable_shared_from_this<Env>
{
public:
    Env();
    bool Initialize();
    static void func(/ some arguments / );
private:
    std::shared_ptr<Info<Env>>_spInfo;
    //other variables
}

Cpp файл:

Env::Env() : _spInfo() // + other variables in initializer list
{
    _spInfo = std::make_shared<Info<Env>>();
}

bool Env::Initialize()
{
    _spInfo->RegisterForChange(FUNC_PTR<Env>func, this->weak_from_this());
}

TEST CASE: (используется cpp catch framework)

Env env;
env.Initialize();

РЕДАКТИРОВАТЬ: Согласно комментариям, спрашивая его правильно, модуль Env будет управляться плагином, который создаст unique_ptr и вызовет Initialize.Что-то вроде:

    template<typename T>
    std::unique_ptr<T> BringUp()
    {
        std::unique_ptr<T> ptr(std::make_unique<T>());
        if (ptr && ptr->Initialize())
            return std::move(ptr);
    }

std::unique_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();

Я все еще сталкиваюсь с той же проблемой.Как мне управлять Env в этом случае?

1 Ответ

2 голосов
/ 12 мая 2019

Ваш строительный код все еще неверен. Чтобы shared_from_this работал, время жизни объекта должно управляться общими указателями. Сначала вы пытались управлять им по объему, а затем пытались управлять им с помощью уникального указателя. Ни один из них не будет работать.

Смысл shared_from_this состоит в том, чтобы разрешить продление времени жизни объекта с помощью кода, который должен его расширять. Чтобы это работало, временем жизни объекта должна управлять какая-то структура, которая позволяет объектам продлевать его жизнь. Область не может этого сделать, потому что, когда область заканчивается, память объекта освобождается. A unique_ptr не может этого сделать, потому что в любой момент времени может существовать только один указатель на объект, поэтому нет способа продлить его жизнь, так как для этого потребуются два указателя (один уже должен существовать, или он будет мертв, и один продлит свою жизнь, будет другим).

Создайте объект Env, используя std::make_shared, и сохраните std::shared_ptr для него.

    template<typename T>
    std::shared_ptr<T> BringUp()
    {
        std::shared_ptr<T> ptr(std::make_shared<T>());
        if (ptr && ptr->Initialize())
            return std::move(ptr);
    }

std::shared_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();
...