C++-允许类中的访问对象访问它们所在的类的推荐方法
C++ - Recommended way to allow access objects in a class to access the class they are in
我有一个类Game
和类EnemyManager
。EnemyManager
处理敌人的生成及其背后的逻辑。问题是EnemyManager
需要访问游戏类中的函数和其他Game
对象。我能想出两种方法来处理这个问题。
-
使用
this
作为EnemyManager
中的参数之一传递类对象Game*
的地址。 -
声明一个指向Game对象的全局指针,并在初始化
Game
类时对其进行设置。然后将其外部化到enemymanager.cpp
中。
哪种方法更可取?
每当我遇到这样的情况时,我都会回顾相关类的总体设计。如果EnemyManager是Game对象的成员,并且需要在Game中调用东西,那么Game中的这些功能可能可以分解为一个单独的组件。如果你正在写的东西开始觉得过于复杂或像黑客一样,通常是时候做一些分解了。
在处理面向对象的设计时,通常最好考虑谁将采取什么行动来找到设计的第一个版本。在编写完这个版本之后,人们经常会发现弱点,并为第二次迭代重写它。
因此,在这种情况下,Game
类管理世界(我认为),并提供了不同的操纵方式。你的EnemyManager
管理世界的一个方面,敌人,但他们确实生活在世界内部。
class Enemy {
public:
Enemy(Location& location, int hitpoints);
bool Move(Direction& direction);
};
class Game {
public:
bool CreateInitialState();
bool AddEnemy(Enemy& enemy);
bool AddBullet(Location& location, Direction& direction, int speed);
void Render();
};
class EnemyManager {
public:
EnemyManager(Game& game);
void MoveEnemies();
};
在第一个版本中,所有类型都将彼此视为适当的类,并通过调用适当的方法来操纵事物。如果你想在游戏中添加新的东西,这几乎不支持扩展游戏。
这就是接口变得方便的地方,您可以尝试思考不同部分将如何交互,而不是应该如何实现它们。
class Canvas {
public:
// Different graphical primitives.
};
class GameObject {
public:
virtual ~GameObject() {};
virtual void Draw(Canvas& canvas) = 0;
virtual bool Move(Direction& direction) = 0;
};
class GlobalState {
public:
virtual AddGameObject(GameObject& gameObject) = 0;
};
class Game : public Canvas, public GlobalState {
public:
bool CreateInitialState();
void Render() {
// Send itself to the Draw method in all GameObjects that have been added
}
// Other game logic
};
class Enemy : public GameObject {
// This can be specialized even more if you need to
};
class Bullet : public GameObject {
// This can also be specialized even more if you need to
};
这将设计与实现分离开来,在我看来,这是一个很好的方式来完成正确的第一次尝试。
如果不了解整体架构布局,很难说,但我的2美分:
您所描述的第一种方式称为依赖项注入,并且在所有方面都被广泛使用。你应该留意你公开的方法/字段。我假设Game
类具有不应该从EnemyManager
类访问的方法,因此创建一个具有EnemyManager
使用的方法声明的接口,然后将指针传递给EnemyManager
实例(而不是Game
)似乎是一个好主意。
例如:Game
类实现了IGameEnemyManager
,您将使用它作为初始化参数之一来传递IGameEnemyManager
。
如果您在EnemyManager
中处理game objects
,为什么它是类Game
的一部分?我想你应该考虑审查你的设计,因为如果你不能很好地处理场景,就有可能出现循环引用问题。
Consider segregating both the classes to ensure a single responsibility principle.
Enemy经理
Define proper interface in yourto Game object as argument and act on the functions
这些都是我能想到的关于你的设计的小建议
您绝对需要使用第一种方法,但有一些更改:您应该将Game
类分解为更多的组件。例如,您可以创建一个SceneManager
类,该类负责所有游戏对象的创建/管理。当您实例化EnemyManager
时,只需向其传递一个指针:
// in SceneManager
EnemyManager* emgr = new EnemyManager(this);
InterfaceManager* imgr = new InterfaceManager(this);
请注意,您的SceneManager
类应该提供一个完整的接口
// in EnemyManager
GameObject* spawnEnemyAt(string name, EnemyClass* eclass, Vector3 position, AIBehaviour* behaviour)
{
GameObject* myEnemy = smgr->createGameObject(name, position, etc...);
//register an enemy in the enemies list, initialize it's behaviour and do any other logic
return myEnemy
}
这种方法应该可以帮助您避免破坏您的体系结构,避免在friend
(类)区域中被捕获。
[Upd.]请注意,我的方法假设场景中的所有对象都是GameObject
s,既没有Enemy
类,也没有Player
类。每个GameObject
可以具有一个Renderer
、Animator
、AIBehaviour
分量。
- 通过方法访问结构
- 为了访问方法,从基类动态转换为派生类
- 访问方法的返回类型
- 是否有对 Clang 递归 ASTVisitor 的最终访问方法
- 具有各种访问方法的自定义数据结构
- 另一个子模块错误的 omnet 访问方法 - 调用 'check_and_cast(cModule*&)' 没有匹配函数
- 使用矢量迭代器访问方法
- 从其他 C++ 文件访问方法
- C++箭头运算符重载.如何获取被访问方法的名称
- 访问方法C++时出现问题
- 易失性成员的访问方法
- 在实例化之前访问方法
- 是否不希望将指针存储在具有不同访问方法的多个容器中?
- 在c++中查看类中基于参数的私有变量的访问方法
- 在继承错误之后访问方法
- 最好的方法访问方法的派生类c++
- 是否存在具有多访问方法的可变模板变体
- 为指向类的指针数组制定访问方法时遇到问题
- 转发类,无法访问方法
- 我可以在 Python 中创建我的 C++ 对象,但无法访问方法