0

After publicly inheriting enable_shared_from_this and initialzing the object of class, while calling another function of that class, i can still see empty weak pointer of enable_shared_from_this_class while debugging in Visual Studio.

All existing questions are due to either privately inheriting from enable_shared_from_this or calling weak_from_this in constructor. This is not the case for me. I am currently using c++ catch framework to test this scenario in visual studio debugger. In Initialize function, i can see, that weak_ptr of this object is empty.

header File :


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 File :

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 : (used cpp catch framework)

Env env;
env.Initialize();

EDIT: As per comments , asking it correcty, the Env module will be managed by a plugin which will create a unique_ptr and call Initialize. Something like:

    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>();

I still face the same issue. How shall i manage Env in this case?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
  • 1
    Its not clear what you expect from this code. `std::enable_shared_from_this` is for objects that are managed by a `shared_ptr`, `env` isnt managed my a smart pointer – 463035818_is_not_an_ai May 11 '19 at 21:53
  • ^^^^ `Env env;` That's a problem right out of the gate. Your class can't just inherit from `std::enable_shared_from_this`. It actually has to be *created* and managed as a `std::shared_ptr`. ex: `auto env = std::make_shared(); env->Initialize();` – WhozCraig May 11 '19 at 22:03
  • i have appended the data to my question to ask it correctly. – Piyush Gupta May 11 '19 at 22:19

1 Answers1

2

Your construction code is still wrong. For shared_from_this to work, the object's lifetime has to be managed by shared pointers. First you tried managing it by scope and then you tried managing it with a unique pointer. Neither of those will work.

The point of shared_from_this is to allow an object's lifetime to be extended by code that needs to extend it. For that to work, the object's lifetime has to be managed by some structure that makes it possible for objects to extend its life. A scope can't do that because when the scope ends the object's memory is released. A unique_ptr can't do that because only one pointer to the object can exist at any time, so there's no way to extend its life as that would require two pointers (one would have to already exist or it would be dead and the one extending its life would be another).

Construct the Env object using std::make_shared and store a std::shared_ptr to it.

    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>();
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • thanks for the detailed explanation. I found a question [link](https://stackoverflow.com/questions/38058060/getting-a-unique-ptr-for-a-class-that-inherits-enable-shared-from-this) where people tried to create a hack but i am not sure if that is the correct way. – Piyush Gupta May 11 '19 at 22:46
  • 1
    You can hack it so that you have a `shared_ptr` with an empty deleter. But the whole point of shared pointers is to permit an object's lifetime to be extended and that would defeat that. – David Schwartz May 11 '19 at 23:13