Reputation: 939
I have several abstract classes that need to manage static vectors containing pointers to every instance of themselves. Here's a simplified example of how one of those classes looks:
class AbstractBase1
{
public:
AbstractBase1()
{
allInstances_.push_back(this);
}
AbstractBase1(const AbstractBase1& source)
: AbstractBase1()
{
//Copy data from source
}
AbstractBase1(const AbstractBase1&& source)
: AbstractBase1()
{
//Copy data from source
}
virtual ~AbstractBase1()
{
//Find the index of 'this' with std::find and remove it from allInstances_
}
virtual void purelyVirtualMethod() = 0;
static void doSomethingWithAllInstances()
{
for (AbstractBase1* ptr : allInstances_)
{
ptr->purelyVirtualMethod();
}
}
private:
static std::vector<AbstractBase1*> allInstances_;
//Some data that will be inherited
};
So rather than having to write all that code for every class that needs this functionality, I figured I would create an InstanceTracker class containing this functionality, and then have all those classes inherit from it. But I can't wrap my head around how this InstanceTracker class would look, since I don't want this class to manage a static vector of all its derived classes' instances. What I want is that each class that inherits from InstanceTracker will get their own static vector that will manage its instances.
Is there a way to achieve this or will I just have to write the instance-tracking code for every class that needs it?
Upvotes: 1
Views: 56
Reputation: 217145
You might use template:
template <typename Tag>
class AbstractBaseT
{
public:
AbstractBaseT() { allInstances_.push_back(this); }
AbstractBaseT(const AbstractBase1& source) : AbstractBaseT()
{
//Copy data from source
}
AbstractBaseT(AbstractBaseT&& source) : AbstractBase1()
{
//Move data from source
}
virtual ~AbstractBaseT()
{
//Find the index of 'this' with std::find and remove it from allInstances_
}
virtual void purelyVirtualMethod() = 0;
static void doSomethingWithAllInstances()
{
for (AbstractBase1* ptr : allInstances_)
{
ptr->purelyVirtualMethod();
}
}
private:
static std::vector<AbstractBaseT*> allInstances_;
//Some data that will be inherited
};
and then
using AbstractBase1 = AbstractBaseT<struct tag1>;
or the CRTP way might also be useful:
struct AbstractBase2 : AbstractBaseT<AbstractBase2>
{
// ...
};
Upvotes: 1