I have a singleton class A
that the user interacts with. A
stores shared pointers to a separate class B
. And within A::doStuff()
, it allows B
to delete B
from the vector in A
that stores the shared pointers.
However, I can't seem to find a way for B
to inform A
about itself. In short, what A
stores != what B
informs A
to delete from itself.
Right now I am just using std::make_shared<B>(*this)
such that the syntax matches but this creates a new instance of B
which doesn't match with b
in main
, hence failure for A
to remove it.
struct B
{
void doStuff()
{
// stuff...
// and then delete itself from A::_vec
A::get().del(std::make_shared<B>(*this));
// with raw ptr, I would do `A::get().del(this);
}
};
Here's the sample code that prints use_count
to help identify whether the same object is attempted to be removed from A
.
I'd expect the shared count at the end of the program to be 1, but it's 2.
class B;
class A
{
std::vector<std::shared_ptr<B>> _vec;
public:
static A& get();
void run();
void add(std::shared_ptr<B> b);
void del(std::shared_ptr<B> b);
};
struct B
{
void doStuff()
{
// stuff...
// and then delete itself from A::_vec
A::get().del(std::make_shared<B>(*this));
// A::get().del(this); // would do this with raw pointer!
}
};
A& A::get()
{
static A obj;
return obj;
}
void A::run()
{
for (auto e : _vec)
{
e->doStuff();
}
}
void A::add(std::shared_ptr<B> b)
{
std::cout << "A::add[1] = " << b.use_count() << std::endl;
_vec.push_back(b);
std::cout << "A::add[2] = " << b.use_count() << std::endl;
}
void A::del(std::shared_ptr<B> b)
{
// removing b from _vec
std::cout << "\n_vec size1 = " << _vec.size() << std::endl;
std::cout << "A::del[1] = " << b.use_count() << std::endl;
_vec.erase(std::remove(_vec.begin(), _vec.end(), b), _vec.end());
// _vec size remains 1 since "b" != what's in _vec
std::cout << "A::del[2] = " << b.use_count() << std::endl;
std::cout << "_vec size2 = " << _vec.size() << std::endl << std::endl;
}
int main()
{
auto b = std::make_shared<B>();
A::get().add(b);
std::cout << "After add = " << b.use_count() << std::endl;
A::get().run();
// remains 2 since _vec.erase wasn't successful!
std::cout << "After remove = " << b.use_count() << std::endl;
}