Extern Break Encapsulation

时间:2015-03-24 18:49:36

标签: c++ c qt oop extern

我是C ++的新手,我正在制作游戏。我有一个名为main的类,我声明了

Game * game; //globally
int main() {
    game = new Game();
    game->show();
}

我的课程游戏启动了我的游戏等等。现在在其他课程(玩家,敌人等)中,我使用

从游戏中访问玩家健康等变量
#include<game.h>
extern Game * game;
func::func() {
    game->health->resetHealth();
}

这打破封装/ ood范式吗?这是不好的做法吗?事情是我可以看到任何其他方式为游戏做到这一点。

5 个答案:

答案 0 :(得分:1)

extern打破了封装。封装的主要概念是数据隐藏和绑定属性以及单个实体中对象的行为。 变量extern会违反法律 在诸如OOP之类的更高级java语言中,没有extern。在Java中,它始终建议将属性/字段设为私有以限制其访问。

答案 1 :(得分:1)

我的意思是,是的,它没有被封装。 game是一个全局指针,可以从任何地方访问和更改。封装是关于数据隐藏的,game完全暴露。它也不是典型的面向对象设计。为了正确封装和OOD,您应该限制谁使用和&#34;了解&#34; Game * game。例如,您可以拥有一个由GameController组成的Game *对象。 Game *的范围和生命周期可以存在于GameController中,然后GameController可以通过将其隐私并决定访问指针的人员,方式和时间来封装其成员变量。还有其他方法,例如将指针包装在全局单例类中。这比你的例子更好,因为包装类可以强制执行某些不变量(比如访问游戏时会发生什么,或者客户端应该如何删除游戏)。通常情况下,出于本答案范围之外的原因,全球单身人士不是最好的方法。另一种方法是使用依赖注入。因此,每当一个类需要修改Game *时,它就会将指针传递给它。这些都是面向对象的技术,用于访问封装数据。

答案 2 :(得分:1)

只是拥有一个全局变量已经开始打破你的封装,因为它提供了对程序中任何代码的对象的访问。如果您拥有像这样的全局任何函数可以生成改变游戏的副作用,甚至是完全不相关的对象实例中的副作用。使用extern不会进一步破坏封装,因为它大致等同于将更多代码粘贴到声明全局的单个源文件中。

答案 3 :(得分:1)

使用全局变量本身不会破坏封装 - 如果对象不是全局变量,则可以尽可能多地隐藏其实现细节。然而,在大多数情况下,它确实与另一个设计原则相冲突:灵活性。比如说,您希望您的程序一次处理多个游戏(如果这样的后续更改根本没有意义,您可以决定将其保持全局)。

每当你要宣布一些全局变量时,问自己也许是好事:

  • 难以避免吗? (在显示的情况下,将game对象传递给需要它的函数会很容易。)
  • 以后可能不仅有一种这样的物体吗? (例如,您可能希望编写一个游戏级别的编辑器,您希望重用某些代码,并且此编辑器应该能够在多个选项卡中编辑多个游戏。)
  • 使用全局强化阅读代码? (请记住,易于阅读比写作更容易!)

在大多数情况下,我认为最好避免全局变量;我认为最好避免问题所示的案例。 game参数可以轻松传递。

答案 4 :(得分:0)

简而言之,是的,这打破了封装。你不断引用游戏对象这一事实表明你对这个对象有依赖性。

你可能会考虑在你的程序中有一个初始化序列,称为组合根,(对于简单的例子,main是最明显的地方),你将这样的所有依赖项传递给需要它们的对象。构造函数,称为依赖注入。

如果您想更进一步,可以创建基类并传递抽象基类而不是实现对象。这样你就可以更多地编程接口而不是对象。