【问题标题】:How would you structure the class interactions in a physics engine? [closed]您将如何构建物理引擎中的类交互? [关闭]
【发布时间】:2014-03-14 19:21:07
【问题描述】:

我正在用 C++ 编写一个物理引擎,但我已经停下来,即我应该如何设计类层次结构。我特别关心的是WorldBody 类。 Body 应该向World 公开一些细节,World 然后可以处理。但同时,我不希望用户能够访问Body 的所有这些属性。但我仍然希望引擎的用户能够改变身体中的一些东西。例如,它的位置。你会如何根据类来组织它?

【问题讨论】:

    标签: c++ oop class-hierarchy


    【解决方案1】:

    定义一个interface(即纯虚拟类),指定您希望从Body 公开哪些功能。让Body 实现该接口。

    允许从World 使用该接口,而不是Body

    这种模式称为组合

    【讨论】:

    【解决方案2】:

    最近,我通过为受限操作引入一个特殊接口,并从中受保护地继承,解决了类似的问题。像这样:

    struct RestrictedBodyFunctions
    {
      virtual void step() = 0;
    
      virtual Body& asBody() = 0;
    };
    
    
    struct Body : protected RestrictedBodyFunctions
    {
      static std::unique_ptr<Body> createInWord(World &world)
      {
        auto Body = std::unique_ptr<Body>{new Body()};
        world.addBody(*body);  // cast happens inside Body, it's accessible
        return std::move(body);
      }
    
      std::string getName() const;
      void setName(std::string name);
    
    protected:
      void step() override
      { /*code here*/ }
    
      Body& asBody() override
      { return *this; }
    };
    
    
    struct World
    {
      void addBody(RestrictedBodyFunctions &body)
      {
        m_bodies.push_back(&body);
      }
    
      void step()
      {
        for (auto *b : m_bodies)
        {
          myLog << "Stepping << " b->asBody().getName() << '\n';
          b->step();
        }
      }
    
    private:
      std::vector<RestrictedBodyFunctions*> m_bodies;
    };
    

    这样,用户可以使用createInWorld 创建Body 对象,但他们只能获得Body 的(公共部分)句柄,而World 获得RestrictedBodyFunctions 的句柄。

    您的另一个选择是扭转上述想法 - 提供受限制的公共接口PublicBody,并让Body 派生自PublicBody。您的内部类将使用完整的Body,而工厂函数确保只有PublicBody 类型的句柄可供客户端使用。这种替代方案的设计更简单,但对谁可以访问全部功能的控制较少。

    【讨论】:

    • 我希望 World 能够完全访问 Body 的内部结构。但仔细想想,可能还有一些其他类,比如ContactJoint,我也想完全访问它。
    • @user3399634 对于“完全访问内部”,您可以使用friend;但这是一个非常紧密的耦合。我会在答案中添加另一个选项。
    • 是的,但我认为系统不会从 WorldBody 的解耦中受益。我有点认为Body 在技术上是World 的一部分,只是一个单独的类,因为我想公开一个漂亮的接口。但是,是的,你可能是对的。如果我想做这样的事情,那为什么不直接使用friend 而不是拐弯抹角。让我们这样说:position 之类的属性,我有点希望它们表现得像 internal(就像在 .NET 中一样)。什么是最好的替代方案,friend 或受限接口?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2011-09-18
    • 1970-01-01
    相关资源
    最近更新 更多