如何使用智能指针跟踪类的对象
How do I track objects of a class using smart pointers?
我正在尝试编写一个对象相互识别的类(即具有指向所有对象的指针)。我无法理解有关智能指针和静态成员的这个想法的实现的某些方面。
可以将该类视为需要能够访问其他游戏对象的成员函数和属性的游戏对象。
据我所知,实现所需设计的常用方法是静态向量,它将包含指向其他对象的指针。如果使用原始指针进行操作,则任务不是很复杂:
游戏对象.h:
#pragma once
#include <vector>
class GameObject
{
private:
static std::vector< GameObject* > objects;
public:
GameObject()
{
objects.push_back(this);
}
};
游戏对象.cpp:
#include "GameObject.h"
std::vector< GameObject* > GameObject::objects = {};
这实际上会提供我需要的东西。但是,如果我想使用智能指针,事情对我来说就不那么简单了。从这个问题和迈耶斯的《有效的现代C++》一书中,我发现了std::enable_shared_from_this
和shared_from_this()
。但是,此外,参考明确指出,只有在对象已经归std::shared_ptr<>
所有的情况下,才允许使用shared_from_this()
。
因此,不可能像以前一样简单地将构造函数中的指针this
(或在其上构造std::shared_ptr
)推入静态向量。我发现的允许设计的最小代码集如下:
游戏对象.h:
#pragma once
#include <vector>
#include <memory>
class GameObject : public std::enable_shared_from_this<GameObject>
{
private:
static std::vector< std::shared_ptr<GameObject> > objects;
public:
GameObject() {}
void emplace_ptr()
{
objects.emplace_back(shared_from_this());
}
};
游戏对象.cpp:
#include "GameObject.h"
std::vector< std::shared_ptr<GameObject> > GameObject::objects = {};
主.cpp:
#include "GameObject.h"
int main(int argc, char* argv[])
{
std::shared_ptr<GameObject> game_object{ new GameObject{} };
game_object->emplace_ptr();
return 0;
}
所以我显然有义务创建一个指向外部某处对象的指针,然后显式调用一个方法来将指针推送到静态向量(因为我不允许在构造函数中这样做)。
我的印象是所需的代码变得不必要地复杂(比较原始指针大小写)或者我正在做一些荒谬的事情。
- 我努力使对象相互感知是否有意义完全?这是一个常见问题还是其他方法通常是采取?
- 静态向量是解决问题的合理解决方案吗?
- 如何使用智能指针构造这样的向量,但最好是无需外部干预,也无需创建特殊功能
emplace_ptr()
为目的?
你不需要enable_shared_from_this
,相反,你可以有一个static
工厂函数来创建(共享)实例,将其放入向量中,并返回它。
类似的东西
class GameObject
{
private:
static std::vector<std::shared_ptr<GameObject>> objects;
// Don't allow creation from outside
GameObject() {}
public:
static std::shared_ptr<GameObject> create()
{
objects.emplace_back(new GameObject);
return objects.back();
}
};
然后要获得一个实例,例如
auto new_game_object = GameObject::create();
这只有一个问题:共享指针指向的对象只要在向量中,就永远不会超出范围,而向量的生存期就是程序的生存期(因为它是static
的)。因此,您必须考虑何时何地从向量中删除这些实例。
我会首先将静态向量移动到游戏对象类之外,并避免将管理游戏对象的代码放在游戏对象本身中。其他用户提出的静态create()方法会有所帮助,但我个人更喜欢自己调用GameObject/Derived game对象构造函数的能力,这样我就可以在构造过程中传递我需要的任何数据。
创建类似 GameObjectWorld 类的内容,您可以在游戏引擎执行期间向其添加对象。无需直接从游戏对象构造函数自动将它们添加到世界中。
您可以执行以下操作:
auto gameObject = std::make_shared<GameObject>();
// implemented at a singleton for simplicity
GameObjectWorld::getInstance().add(gameObject);
过去,我采用的方法是,给定的游戏"部分"或"场景"维护自己的游戏对象(实体)列表,而游戏对象(实体)又维护自己的列表。这允许您通过递归来执行操作,并具有对象层次结构的额外好处。
这是一个粗略而简单的例子:
class Part
{
std::vector<std::shared_ptr<GameObject> children;
public:
void addChild(std::shared_ptr<GameObject> object)
{
children.push_back(object);
}
// Part lifecycle
virtual void onCreate() = 0; // must be provided by your parts
};
class GamePart :: public Part
{
void onCreate() override; // called by your engine
};
void GamePart::onCreate()
{
addChild(std::make_shared<GameObject>());
}
这是开始管理游戏对象的一种非常简单的方法,我强烈建议您阅读"实体组件系统"并了解行业专家管理其游戏世界的一些方式。
- C++:跟踪类对象
- MATLAB:跟踪imufilter对象中的状态变化
- mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库
- 内存分配究竟是如何发生的,Java和C如何交互以跟踪同一对象?
- 如何在类中声明一个变量,该变量将跟踪已创建 c++ 的对象计数
- 从实时摄影机馈送而不是图像中按形状跟踪对象
- 如何清理本地引用中跟踪C++对象<External>?
- 如何确定我跟踪的对象球是否越过我绘制的线
- 跟踪对象类型
- 丢失后再次找到的对象跟踪
- 使用本地二进制模式进行对象跟踪:更改检测ROI的大小
- OpenCV C++简单的对象跟踪
- opencv 卡尔曼滤波多对象跟踪错误
- 使用开放CV进行对象跟踪
- 增强序列化-启用对象跟踪
- 实现对象跟踪,如在 Boost::Serialization 中
- 如何在opencv中使用对象跟踪的概念移动鼠标
- Opencv对象跟踪和计数在视频帧中通过ROI的对象
- 使用OpenCV的对象跟踪脚本中的慢速视频
- OpenCV中鸟瞰中的实时对象跟踪