Question

I have two classes, for instance, A and B. I would like to pass A as reference to B.

class I
{
public:
    virtual void callback() = 0;
};

class B
{
public:
    B(I* callback) : _callback(callback) {}
private:
    I* _callback;
};

class A : public I
{
public:
    A() : _b(new B(this)) {}
private:
    B* _b;
};

And I would like to:

  1. get rid of naked pointers (for instance, with a help of std::shared_ptr and std::weak_ptr).
  2. avoid cyclic referencing.

But there are some problems:

  1. How do I create a weak pointer INSIDE a class A? First, I should be sure that an instance of A is managed by some shared_ptr. Even if I'm really sure, how can I find this shared_ptr instance?
  2. Generally, how can I ensure that I'm using instances of some class ONLY via shared pointers? I can try to create factory method and make constructor private, but it leads to error: make_shared demands a public contstructor.

Thanks in advance!

EDIT:

More detail explanation of problem: I have a class A. This class wants to pass some part of work to a class B. So I have a shared pointer to B inside A. And I would like B to do this asynchronously, and B should call A's callback when there is some progress or when the work is done. So B should have a reference to A.

class I
{
public:
    virtual void isDone() = 0;
};

class B
{
public:
    B(I* callback) : _callback(callback) //how do I take and store callback inside B???
    {
        //async invocation of run()
    }
private:
    weak_ptr<I> _callback;

    void run()
    {
        if(_callback.get())
        {
            _callback->isDone();
        }
    }
};

class A : public I
{
public:
    A() : _b(new B(this)) {} //how do I pass this to B???
private:
    shared_ptr<B> _b;

    virtual void isDone()
    {
        cout << "job is complete" << '\n';
    }
};

So the question is: how do I pass A to B? I can try to do it via naked pointer or reference, but it's safety because B has no guarantees that this referenced object is still alive (common problem of all naked pointers). So I would like to pass a weak pointer, and my question was all about it.

Was it helpful?

Solution

The first problem can be solved with std::enable_shared_from_this, which allows you to safely create a shared pointer instance from within class A.

The second problem may be solved by using a static factory method belonging to class A and not using std::make_shared like this:

static std::shared_ptr<A> create() {
    return std::shared_ptr<A>(new A());
}

Then, you can make A's constructor private.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top