C++ 如何应用DOP并保持良好的用户界面?

C++ 如何应用DOP并保持良好的用户界面?,c++,caching,vector,relocation,data-oriented-design,C++,Caching,Vector,Relocation,Data Oriented Design,目前,我想优化我的3d引擎控制台一点。更确切地说,我希望缓存更加友好,结构更加面向数据,但也希望保持良好的用户界面 例如: bool Init() { // Create a node ISceneNode* pNode = GetSystem()->GetSceneManager()->AddNode("viewerNode"); // Create a transform component ITransform* pTrans = m_pNode->Cr

目前,我想优化我的3d引擎控制台一点。更确切地说,我希望缓存更加友好,结构更加面向数据,但也希望保持良好的用户界面

例如:

bool Init()
{
  // Create a node
  ISceneNode* pNode = GetSystem()->GetSceneManager()->AddNode("viewerNode");

  // Create a transform component
  ITransform* pTrans = m_pNode->CreateTransform("trans");
  pTrans->SetTranslation(0,1.0f,-4.0f);
  pTrans->SetRotation(0,0,0);

  // Create a camera component
  ICamera* pCam = m_pNode->CreateCamera("cam", pTrans);
  pCam->LookAt(Math::Vec3d(0,0,0));

  // And so on...
}
因此用户可以在代码中使用接口指针

但是
在我的引擎中,我当前存储指向场景节点的指针

boost::ptr_vector<SceneNode> m_nodes
boost::ptr_向量m_节点
因此,在面向数据的设计中,最好使用数组结构,而不是数组结构。所以我的节点来自

class SceneNode
{
private:
  Math::Vec3d m_pos;
};

std::vector<SceneNode> m_nodes;
类场景节点
{
私人:
数学:Vec3d m_pos;
};
std::向量m_节点;
对此

class SceneNodes
{
  std::vector<std::string> m_names;
  std::vector<Math::Vec3d> m_positions;
  // and so on...
};
类场景节点
{
std::向量m_名称;
std::向量m_位置;
//等等。。。
};
因此,如果我想应用DOP,这里有两个问题。 首先,在没有用户使用ID、索引等的情况下,我如何保持良好的用户界面

第二,当一些向量调整大小而不让用户界面指针指向涅盘时,我如何处理属性的重新定位

目前我的想法是实现一种handle_向量,从中可以获得持久“指针”的句柄:

typedef handle sceneodehandle;
SceneNodeHandle nodeHandle=nodeHandleVector.get_handle(idx);
因此,当intern std::vector调整大小时,它会更新其句柄。 “句柄”存储一个指向实际对象的指针,“->”操作符被重载以获得良好的包装效果。但这种方法听起来很复杂

你觉得怎么样?如何保持一个好的接口,但保持内存中的连续性以更好地使用缓存


谢谢你的帮助

您需要使用比原始指针更智能的句柄。DOP是没办法解决的

这意味着:

class SceneNode
{
public:
  std::string const& getName() const { mManager->getSceneName(mId); }
  void setName(std::string const& name) { mManager->setSceneName(mId, name); }

  // similar with other data
private:
  ISceneManager* mManager;
  size_t mId;
};
不过有一点很好:用户不能意外地对您现在返回的指针之一调用
delete
。这就是为什么智能手柄总是更好


另一方面:您将如何处理
mManager
指针的生命周期是另一个问题:-)

对于那些对DOP的实际示例感兴趣的人,请看一下Niklas Frykholm=>


这有助于我以面向数据的方式实现场景图。

是的,我也朝着这个方向思考,但对我来说,它似乎不是很优雅。。。但我想我会选择这样的解决方案,并对用户隐藏索引。在我的设计中,所有的“经理”都是全球性的。因此,在调试模式下使用一个简单的assert()来确保我们有一个有效的管理器是不够的。这是DOP的一大缺点。谢谢大家!@VitaminCpp:就我而言,这并不是一个真正的缺点,因为我在设计界面时总是使用智能手柄。更容易发展,可能包括透明的引用计数,保护内容,并可能更容易提供二进制兼容性。事实上,这是一个强有力的论点!现在最困难的部分是重新建模场景节点本身DOP…:(非常感谢!在我的示例中,面向数据的编程是从结构数组到数组结构的转换。虚拟更新()方法从场景节点中提取,然后是场景节点结构的一个成员。因此,我可以对我感兴趣的数组进行线性转换。
class SceneNode
{
public:
  std::string const& getName() const { mManager->getSceneName(mId); }
  void setName(std::string const& name) { mManager->setSceneName(mId, name); }

  // similar with other data
private:
  ISceneManager* mManager;
  size_t mId;
};