【问题标题】:Sharing access to member variable from multiple classes从多个类共享对成员变量的访问
【发布时间】:2015-04-14 07:54:32
【问题描述】:

考虑以下示例

class GameObject {
  vec3 position;
  SphereCollider collider;
  // ...
};

SphereCollider* GameObject::getCollider(){
  return &collider;
}


class SphereCollider {
  vec3 position;
  float radius;
};

您可以注意到,在这个设计中,成员变量position 的重复性在多个类之间共享。 radius 用于显示可能存在其他数据成员。

SphereCollider 稍后用于碰撞检测,我有更多的 GameObject 类(没有共同的祖先)组成 SphereCollider。

在设计和性能方面处理这种情况的最简洁方法是什么?这里面有约定吗?

我想到的解决方案很少,但没有一个是完美的。你能想出更好的解决方案吗?

1) 通过 getter/setter 的持久数据成员访问

缺点:不能直接访问类内的数据成员。是否有一个约定可以将这个真相告诉将在这个类上进一步工作的程序员?

void GameObject::setPosition(vec3& pos){
  position = pos;
  colliser->setPosition(pos);
}

vec3 GameObject::getPosition(){
  return position;
}

2) 删除冗余并使用 getter/setter 访问 SphereCollider

缺点:类似于 1)

class GameObject {
  SphereCollider collider;
};

void GameObject::setPosition(vec3& pos){
  colliser->setPosition(pos);
}

3) 从 SphereCollider 到 GameObject 数据成员的引用/指针

缺点:重新分配(例如 std::vector)游戏对象可能会导致麻烦。有没有办法告诉这个类的用户?

class GameObject {
  vec3 position;
  SphereCollider collider;
public:
  GameObject(){
    collider = SphereCollider(position);
  }
};

class SphereCollider {
  const vec3& position;
  float radius;
public:
  Collider(vec3& pos)
    : position(pos)
  {
  }
};

4) 按需将数据传播到 SphereCollider

缺点:用户可以使用 getCollider() 存储对碰撞器的引用并跳过;

SphereCollider* GameObject::getCollider(){
  collider->setPosition(position);
  return &collider;
}

【问题讨论】:

    标签: c++ oop


    【解决方案1】:

    说具体的选择可能取决于各种更通用的设计因素,我更喜欢你的选择(3)。您可以通过定义GameObject 的正确移动构造函数轻松解决向量调整大小的问题:它会在需要时被调用。

    例如查看这些问题/答案:

    Why does resize() cause a copy, rather than a move, of a vector's content when capacity is exceeded?

    How to enforce move semantics when a vector grows?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2018-03-19
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多