以支持继承的方式将自身shared_ptr添加到对象构造函数中的向量中
Adding shared_ptr to self to vector in constructor of object in a way that supports inheritance
我希望在创建对象时自动将对已创建对象的引用添加到向量(通常是多个向量(中。为了提供一些上下文,此代码将在游戏中用于游戏对象集(可绘制、可碰撞、敌人等(,因此需要多个向量。
这里显示了我试图实现的目标的示例:
#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;
}
在此代码中,shared_from_this()
的使用无法正常工作,因为它位于构造函数中(如此处所示(。以前我已经使用单独的静态函数克服了这个问题,例如:
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);
}
然而,在从单个基类派生多个类的上下文中,并且每个派生类也可以添加到其他向量中,代码重复成为一个问题(BaseList.push_back(P)
应该为每个继承BaseClass
的对象调用,因此必须在X
继承的每个X::MakeOne()
中编写BaseClass
(。
我也通过简单地使用原始指针(std::vector<BaseClass*>
(来克服这个问题,但是当对象在多个地方被引用时,这失去了简单内存管理和引用计数的好处。在这种情况下,是否有更好的内存管理选择?
我认为这可以通过使用工厂/提供者来解决。
class SomeBaseClass // Could also be an interface or similar
{
};
// Instead of having SomeBaseClassFactory instance, all the methods could also be static
class SomeBaseClassFactory
{
public:
std::vector<std::shared_ptr<SomeBaseClass>> someBaseClassList;
std::shared_ptr<SomeBaseClass> GenerateObject(/* Parameters */)
{
std::shared_ptr<SomeBaseClass> someBaseClass = std::make_shared<SomeBaseClass>(/* Parameters */);
RegisterObject(someBaseClass);
return someBaseClass;
}
protected:
void RegisterObject(std::shared_ptr<SomeBaseClass> objectToRegister)
{
someBaseClassList.push_back(objectToRegister);
}
};
class SomeDerivedClass : public SomeBaseClass
{
};
class SomeDerivedClassFactory : public SomeBaseClassFactory
{
public:
std::shared_ptr<SomeDerivedClass> GenerateObject(/* Parameters */)
{
std::shared_ptr<SomeDerivedClass> someDerivedClass = std::make_shared<SomeDerivedClass>(/* Parameters */);
RegisterObject(someDerivedClass);
return someDerivedClass;
}
};
您可以像这样为对象定义工厂:
#include <iostream>
#include <memory>
#include <vector>
class Factory
{
public:
template<class T, class ... Args>
static std::shared_ptr<T> Make(Args... args)
{
auto instance = std::shared_ptr<T>(new T(args...));
T::List.push_back(instance);
return instance;
}
};
class BaseClass
{
friend class Factory;
protected:
BaseClass()
{
std::cout << "Base Created"<<std::endl;
}
public:
virtual ~BaseClass()
{
std::cout << "Base Deleted"<<std::endl;
}
static std::vector<std::shared_ptr<BaseClass>> List;
};
class DerivedClass : public BaseClass
{//for example "enemy"
friend class Factory;
DerivedClass()
{
std::cout << "Derived Created" << std::endl;
}
public:
~DerivedClass()
{
std::cout << "Derived Deleted" << std::endl;
}
static std::vector<std::shared_ptr<BaseClass>> List; //shared_ptr of baseclass can point to derivedclass
};
std::vector<std::shared_ptr<BaseClass>> BaseClass::List;
std::vector<std::shared_ptr<BaseClass>> DerivedClass::List;
int main()
{
auto base = Factory::Make<BaseClass>();
auto derived = Factory::Make<DerivedClass>();
}
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- Qt和C++:将QLineEdit添加到QTabWidget中
- 将QIcon添加到QTableView单元格
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- CLANG 编译器 说:变量"PTR"可能未初始化
- 添加对共享ptr的引用会增加引用计数吗?