外部是否破坏封装
Does Extern Break Encapsulation
我是C++的新手,我正在创建一个游戏。我有一个叫main的类,我在其中声明
Game * game; //globally
int main() {
game = new Game();
game->show();
}
我的职业游戏启动了我的游戏等。现在在其他职业(玩家、敌人等)中,我使用访问游戏中的变量,如玩家健康状况
#include<game.h>
extern Game * game;
func::func() {
game->health->resetHealth();
}
这是打破封装/ood范式吗?这是不好的做法吗?问题是,我可以在比赛中看到任何其他方式。
是的,extern
破坏了封装。封装的主要概念是数据隐藏和绑定单个实体中对象的属性和行为。使变量extern
会违反法律
在一些更先进的OOP
语言中,如java
,没有extern
。在Java中,它总是建议将属性/字段设置为私有,以限制其访问。
我的意思是,是的,它没有封装。game
是一个全局指针,可以从任何地方访问和更改。封装就是数据隐藏,game
是完全公开的。它也不是典型的面向对象设计。为了进行适当的封装和OOD,您应该限制谁使用和"了解"Game * game
。例如,可以有一个由Game *
组成的GameController
对象。Game *
的作用域和生存期可以存在于GameController
中,然后GameController
可以通过将其设为私有变量并决定谁、如何以及何时访问指针来封装其成员变量。还有其他方法,比如将指针封装在全局单例类中。这比您的示例要好,因为包装类可以强制执行某些不变量(比如访问游戏时应该发生什么,或者客户端应该如何删除游戏)。通常,全局单态不是最好的方法,原因不在这个答案的范围内。另一种方法是使用依赖注入。因此,每当一个类需要修改Game *
时,它都会将指针传递给它。这些都是访问封装数据的面向对象技术。
只要有一个全局变量就开始破坏封装,因为它可以从程序中的任何代码访问对象。当你有一个类似的全局时,任何函数都会产生改变游戏的副作用,甚至是在完全不相关的对象实例中。使用extern不会进一步破坏封装,因为它大致相当于将更多代码粘贴到声明全局的单个源文件中。
使用全局变量本身不会破坏封装——如果对象不是全局的,它可以尽可能多地隐藏其实现细节。然而,在大多数情况下,它确实与另一个设计原则相冲突:灵活性。比方说,你希望你的程序一次处理多个游戏(如果以后的更改根本没有意义,你可能会决定保持全局性)。
每当你准备声明某个全局变量时,问问自己:也许是件好事
- 会很难避免吗?(在所示的例子中,只需将
game
对象传递给需要它的函数就可以了。) - 有没有可能在以后的某个时间点上不只有一种这样的物体?(例如,你可能想为游戏的级别编写一个编辑器,在那里你想重用一些代码,这个编辑器应该能够在多个选项卡中编辑多个游戏。)
- 使用全局硬化读取代码吗?(记住,读起来容易比写起来容易重要得多!)
在我看来,在大多数情况下,最好避免全局变量;我认为对于问题中所示的情况,最好避免这种情况。game
参数可以很容易地传递。
简而言之,是的,这会破坏封装。你不断引用游戏对象的事实表明你对这个对象有依赖性。
你可以考虑在你的程序中有一个初始化序列,称为composition root(对于简单的例子来说,main是最明显的地方),你可以通过构造函数将所有这样的依赖项传递给需要它们的对象,这被称为依赖项注入。
如果你想更进一步,你可以创建基类并传递抽象基类,而不是实现对象。通过这种方式,您可以更多地针对接口而不是对象进行编程。
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 是否有更好的方法来封装成员对象可以访问的共享存储池?
- 使用 stl 迭代器封装向量是否很好?如果是?怎么可能呢?
- 假设钻石继承打破了C++的封装是否正确?
- 我是否应该将最后一个“返回”语句封装为“else { return .. }',如果它在逻辑上是可选的
- 外部是否破坏封装
- 传递 lambda 在使用私有成员变量时是否违反封装
- 这里是否违反了封装的概念
- 对象切片是否会破坏封装
- 我的GLSL着色器对象/包装器是否应该封装加载/设置VertexArrayObject
- 公共静态常量变量是否破坏了封装意识形态