Suppose we have a class Bar
which has two data members, a
and b
respectively pointing to two other objects of type A
. Within this type A
, we have a data member i
that points to an integer.
In the code below, in order to allow the data members of Bar
, i.e. a
and b
to share the same pointer i
. I have to create another data member inside Bar
that represent the common pointer a
and b
are going to share.
However, I'm wondering if there's any way of sharing the same intermediate pointer i
when initializing a
and b
in the initializer list.
#include <memory>
using namespace std;
struct A {
const shared_ptr<int> i;
explicit A(const shared_ptr<int> &i): i(i) {}
};
struct Bar {
const shared_ptr<int> _i;
const unique_ptr<A> a;
const unique_ptr<A> b;
explicit Bar(const int &i):
_i(make_shared<int>(i)),
a(make_unique<A>(_i)),
b(make_unique<A>(_i)) {}
};
CodePudding user response:
Since A::i
is public
and is a shared_ptr
, you can eliminate the need for Bar::_i
like this:
struct Bar {
const unique_ptr<A> a;
const unique_ptr<A> b;
explicit Bar(const int &i):
a(make_unique<A>(make_shared<int>(i))),
b(make_unique<A>(a->i)) {}
};
If A::i
is later made private
, simply make Bar
be a friend
of A
, then it should still work.
With the old code, you could have done this:
struct Bar {
const A* a;
const A* b;
explicit Bar(const int &i):
a(new A(new int(i))),
b(new A(a->i)) {}
};
But you would have had a management problem in deciding who is responsible for freeing the int*
. With shared_ptr
, you don't have to worry about that.