gpt4 book ai didi

c++ - 我会因单例过度而感到过度杀伤力吗?

转载 作者:可可西里 更新时间:2023-11-01 16:27:30 25 4
gpt4 key购买 nike

我是C++的新手,正在编写一个跨平台(桌面/移动)2D游戏引擎...我的问题是,我是否以适当的方式使用单例,如果没有,是否有替代方法?

基本上,我的引擎中有一些组件是围绕单例对象构建的。例子:

VBOManager(单人)
这个“管理器”基本上负责分配,当然,“管理”用于存储纹理映射和顶点坐标的vbo。我通过此对象控制“读/写”,因此我可以缓存其他对象写入vbo的数据并返回指针(避免存储重复的数据,例如具有相同映射和顶点坐标的500个 Sprite )。

TextureManager(Singleton,自我解释)

GLUtils(单人)
我几乎用它来统一通用的GL调用,这些调用根据当前平台(例如GL或GLES)而有所不同。例如,GLU函数(libglu不在android上,因此我有一个自定义实现)

图形(Singleton)
用于处理诸如窗口初始化和大小调整,全局帧率管理,视口(viewport)初始化等工作。

InputManager(Singleton,自我解释)
无论如何,所以在这里我正在审查所有这些内容,并且开始感到非常肮脏。我确实认为,鉴于给定对象的要求和功能,这是合理的。但是,另一方面,我是一个新手,对于在我的代码中如此猖“的“模式”感到不对劲。如果确实是后者,那有什么替代方案?

最佳答案

在开始之前,我想弄清楚我们在说什么,以便我们都在同一页面上。单例是:

  • “对象”,这意味着它具有某些内部状态,该状态被封装为直接外部访问。它具有生命周期:它在程序执行的某个时刻创建,并在以后的某个时刻销毁。
  • “最多只能创建一个实例”,这意味着存在一些明确的机制,这些机制强制阻止创建多个实例。构造函数和析构函数在程序执行中将被调用一次。
  • “可全局访问。”一旦创建实例,就可以通过全局函数调用或类的公共(public)静态成员对其进行访问。

  • 全局对象不是单例。它只是一个全局对象。如果可以制作多个,则不是单例。

    现在,定义已不复存在:

    VBOManager (Singleton)



    我无法想象该对象如何以任何有意义的方式工作。就OpenGL而言,缓冲区对象是独立的构造。他们彼此之间没有关系。所以我不明白为什么您需要一个经理来处理所有这些问题。

    我可以理解拥有专门的包装缓冲区对象类来处理流缓冲区对象。有几种方法可以进行流传输,有些方法的性能要比其他方法更好。因此,将其包装在一个对象中是有意义的。

    但是拥有一个全局缓冲区对象管理器是没有意义的。缓冲区对象应该彼此独立。或者,如果有的话,它们应该依赖于其他对象,例如网格物体(多个网格物体可以引用相同的缓冲区)。但是,您不必具有全局缓冲区对象管理器。

    我可以理解拥有一个命名对象的存储库,可以从中添加和检索它们。但是我不理解对于像这样的特定对象类型是否需要它。使其成为全局单例的需求令人怀疑。

    我发现单例最适合根本上唯一的概念。有一个文件系统,因此拥有一个全局文件系统是有意义的。 OpenGL本身是全局的(由于其基于C的本质),尽管即使那样,也可以切换渲染上下文。如果有两个东西有意义,那么单例可能不是最好的选择。

    即使您仅使用单个缓冲区对象并为其提供管理器,也无需使此类成为单例。您可以根据需要将其设置为全局变量,但是不必强制阻止用户创建多个此类的实例。如果以后要使用多个缓冲区对象管理器(并可能要为性能付出代价),就这样吧。

    GLUtils (Singleton)



    为什么这是一个对象?单例模式指的是一个对象,在任何时候都只能有一个实例。效用函数只是全局函数。

    C++不是Java。您不必将所有内容都放在一个类中。全局功能不是坏设计。确实,在适当的情况下,它们是好的设计。如果一个函数不需要访问任何状态(除了它的参数和它可能调用的任何其他函数之外),那么就不需要它成为对象的一部分。

    Graphics (Singleton)



    对于这一点,可以认为Singleton是有意义的。它是有状态的生命物体。而且您明确希望在您的应用程序中不要多个。

    但是,请考虑这一点。拥有一个以上是很错误的吗?您将多久传递一次此 Graphics对象?在 Graphics对象级别需要工作多少代码?我猜不是很多。一些基本的初始化代码,仅此而已。

    因此,尽管这是有根据的,但没有必要。这不是一个必须成为Singleton的概念。另外,由于能够拥有多个,您可以随时将其删除并创建一个新的。这使您的应用程序能够更轻松地重建窗口。

    这样做的一个缺陷是可能同时具有两个 Graphics对象。这涉及到处理OpenGL上下文。由于OpenGL上下文是全局状态,因此拥有多个 Graphics对象可能会导致问题,因为这两个对象都有自己的上下文。您将需要某种方式将特定的 Graphics对象设置为当前对象,该对象将自身绑定(bind)为当前OpenGL上下文(并检索所需的任何函数指针)。

    关于c++ - 我会因单例过度而感到过度杀伤力吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8177427/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com