I want references to created objects to be automatically added to a vector (often multiple vectors), when the objects are created. To give some context, this code will be used in a game for sets of game objects (Drawable, Collidable, Enemies, etc) hence the need for multiple vectors.
An example of what I am trying to achieve is shown here:
#include <iostream>
#include <memory>
#include <vector>
class BaseClass :public std::enable_shared_from_this<BaseClass>
{ //for example "drawable"
public:
BaseClass()
{
std::cout << "Base Created"<<std::endl;
BaseList.push_back(shared_from_this());//I want to put a reference to this object in a vector
}
~BaseClass()
{
std::cout << "Base Deleted"<<std::endl;
}
static std::vector<std::shared_ptr<BaseClass>> BaseList;
};
class DerivedClass :public BaseClass
{//for example "enemy"
public:
static std::vector<std::shared_ptr<BaseClass>> DerivedList; //shared_ptr of baseclass can point to derivedclass
DerivedClass()
{
std::cout << "Derived Created" << std::endl;
DerivedList.push_back(shared_from_this());//reference to this object in a vector in addition to the other vector
}
~DerivedClass()
{
std::cout << "Derived Deleted" << std::endl;
}
};
std::vector<std::shared_ptr<BaseClass>> BaseClass::BaseList;
std::vector<std::shared_ptr<BaseClass>> DerivedClass::DerivedList;
int main()
{
std::shared_ptr<BaseClass> C = std::make_shared<BaseClass>();
std::shared_ptr<BaseClass> D = std::make_shared<DerivedClass>();
BaseClass::BaseList.clear(); //C should be deleted, D should not since it is still in DerivedList
DerivedClass::DerivedList.clear(); //now D should be deleted
return 0;
}
In this code, the use of shared_from_this()
does not work correctly, since it is in a constructor (As Shown Here). Previously I have overcome this issue using separate static functions, for example:
void BaseClass::makeOne()
{
std::shared_ptr<BaseClass> P(new BaseClass());
BaseClass::BaseList.push_back(P);
}
void DerivedClass::makeOne()
{
std::shared_ptr<BaseClass> P(new DerivedClass());
BaseList.push_back(P);
DerivedList.push_back(P);
}
however in a context where multiple classes are derived from a single base class, and each derived class may also be added to other vectors, code duplication becomes an issue (BaseList.push_back(P)
should be called for every object that inherits BaseClass
, and hence must be written in every X::MakeOne()
where X
inherits BaseClass
).
I have also overcome this issue by simply using raw pointers (std::vector<BaseClass*>
) however this loses the benefit of simple memory management and reference counting when objects are referenced in multiple places. Is there a better option for memory management in this situation?