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.
