好或坏:制作巨型结构以避免使用结构的全局/属性/大量参数

Posted

技术标签:

【中文标题】好或坏:制作巨型结构以避免使用结构的全局/属性/大量参数【英文标题】:good or bad: to make giant struct to avoid using globals / properties of a struct / lots of paramerters 【发布时间】:2012-02-04 22:49:20 【问题描述】:

我是一个初学者,我已经用 C++ 编写了一个 10000 行的程序,该程序主要使用全局函数和 void 函数。

无论如何,我的程序没有 GUI,所以我正在使用 Clutter 为它制作一个。所以在混乱中,你使用信号处理函数来连接按钮点击、运动事件等。

信号处理函数只能接受一个用户数据参数。然而,GUI 的许多组件,数百个需要由不同的功能访问。所以我将我所有的 GUI 对象放在一个结构中,并从每个信号处理函数中传递它。

所以我现在的程序(控制台程序)打印了一些字母来做某事。如果你按下那个字母,启动某个功能。如果我不使用全局变量,我需要将其中一些变量作为参数传递。

如果我直接将我的代码插入到 GUI 中,那么信号处理函数将启动适当的函数,但只能传递一个用户数据参数,现在它已经被用作具有数百个 GUI 的结构成员。

对不起,如果这一切听起来很疯狂。我只是想重新编写我的代码以使用更好的做法,但是对于 10000 长的代码,以及我对某些事情缺乏了解,我感到非常不知所措。

我只是在寻找一些关于从哪里开始以及如何处理我在连接到 GUI 时遇到的问题的建议。

关于结构的问题。我有兴趣知道结构内是否有最大数量的元素。如果结构中有一个数组,该数组的访问时间会变慢吗?结构的内存处理方式是否存在差异。

谢谢。

【问题讨论】:

如果你真的有 10000 行这样写的代码,用适当的技术重新开始可能比修改它更容易 “GUI 的许多组件,数百个需要由不同的函数访问” - 听起来您应该尝试模块化代码。 你看过课程吗?它们应该可以帮助您更好地构建代码。这样你就可以让变量接近它们所属的东西。在不知道问题的情况下,这有点困难。我没有处理过混乱,但我猜你会传递一个指向特定类的指针。或者它自己的处理程序可能是特定类的方法。 另外,如果您想要普通的旧 GUI(按钮、列表、标签等),我不认为 Clutter 是最佳选择,Qt 或 GTK+ 应该更容易,而且它们更主流. 【参考方案1】:

我认为您的问题有一个隐藏的问题:如何编写 GUI 应用程序/框架?

从我快速搜索的结果来看,杂乱程度似乎很低。如果你想跳过很多编码,只需使用 Qt Framework 之类的东西,它也使用 OpenGL(或 GTK+,取决于你想要什么样的许可证)呈现大多数东西。

如果您想或多或少地从头开始编写它,没有简单的答案,我将尝试在一个非常高的层次上复习它,并强调它通常是如何工作的非常基本的想法。

既然你用 C++ 标签标记了它,那么正确的 C++ 方式是使用类。

您将拥有诸如声音 (MP3) 之类的类,具有解码、编码等方法。然后您将拥有用于 GUI 元素的类,具有诸如 onPaint、onClick 等方法。

假设您想要一个按钮。它将是一个具有变量的类,例如 x、y、宽度、高度、文本、clickHandler、启用等。它会有一些低级别的事件处理程序,例如 onPaint、onClick(这个会检查鼠标是否在按钮上以及它是否已启用,如果所有这些检查都通过,它将调用 clickHandler)。它可能还有一些方法,如 isEnabled()、disable()、enable() 等。

现在您可以随意创建任意数量的按钮实例,每个实例都有自己的状态(启用或禁用、文本、宽度、高度,所有这些)。您将为每个按钮设置一个 clickHandler。

会有一些全局变量,但大多数内部内容都在类中。如果您有某种层次结构,例如一个窗口有很多按钮,那么您的 Window 类将只有一个按钮列表。并且不要忘记每个类都应该在一个新文件中,除非有多个密切相关的非常

但实际上你不想写任何这样的东西,因为已经有大量的图书馆在做。

至于如何将它们粘合在一起,您可能希望遵循您选择的特定框架所使用的约定。如果您在 Windows 上并且想要制作仅限 Windows 的应用程序,请使用 WPF(或 Winforms)。 Qt 非常适合跨平台的东西,而且它非常现代,但如果你正在制作商业应用程序,许可证会有点限制。

【讨论】:

谢谢。我已经将 GTK 作为 clutter 包的一部分,并且 api 与 clutter 非常相似,所以我将尝试一下。实际上有一个库,clutter-gtk,它可以让我将 GTK 小部件嵌入到 clutter 中。已经发现我可以在混乱中使用 GTK 文件选择器对话框之类的东西,连接到混乱阶段。我曾计划使用 boost 文件系统制作自己的文件选择器对话框,但想想就有点压力。 @MVTCplusplus,啊,我明白了,将它作为依赖项实际上是有道理的。在这种情况下,您可以浏览一些基于 GTK+ 的开源项目(例如 github.com/…)并检查应用程序的结构,您可能会从中获得一些好主意。至于文件打开对话框,我认为最好使用操作系统提供的对话框(或者在您的情况下使用 GTK,它应该只使用当前的操作系统文件打开对话框),因为大多数用户都习惯了它,它还包含由设置的历史记录和收藏夹用户。【参考方案2】:

访问结构内的元素总是会因为需要执行额外的引用而变慢,因此需要额外读取 RAM。尝试将对象分组到 structs 中,以便它们一起使用,以便这些内存请求可以缓存在更快的 RAM/板载缓存中。

结构成员并没有真正的限制,当您超过函数应采用的最大参数数量时,它们通常很有用,我被教导(2002 年)幻数是 7。

最终,当将成员分组到 structs 中时,您应该能够识别哪些函数使用它们,而不是传递结构,您可以使函数成为成员,并取消它必须取消引用结构才能获得它参数的成员。我认为此时您可能可以授予structs 等效的C++ 标签class

【讨论】:

“访问结构内的元素总是比较慢,因为要执行额外的引用,因此需要额外读取 RAM。”在大多数情况下,情况并非如此。一个函数的 7 个参数是一个非常大的数字。将概念整合到结构中会简化这一点。 @CaptainGiraffe 7 是上限,一些自动化工具会产生 100 个。好的,一些 cpu 提供间接作为其操作码的一部分,但如果您也取消引用指针,那么它就用完了。同样的处理可能适用于类,但它是面向对象方法的一个很好的论据。

以上是关于好或坏:制作巨型结构以避免使用结构的全局/属性/大量参数的主要内容,如果未能解决你的问题,请参考以下文章

O/R 映射器 - 好或坏

局部变量 全局变量和存储属性

将全局内存用于(大)本地/私有温度。 OpenCL 中高效的数据结构

如何Word制作小书籍

数组(结构类型)的 Where 是不是已优化以避免不必要地复制结构值?

如何使用 ForEach 中制作的 TextField 更新结构的属性