C++ - 整个程序持续时间的单个本地类实例

发布于 2024-11-13 06:11:07 字数 654 浏览 4 评论 0原文

我正在用 C++ 开发一个小游戏引擎,并决定全部以 OOPily ​​方式完成(大量使用类。) 它的目的是(理论上)跨平台,所以我有一个“引擎”类,它的一个实例是由“操作系统模块”创建的,即 Windows 的 WinMain(我首先为其开发它的平台)。

我有三个主要问题:

  1. 创建一个在整个应用程序中只实例化一次的类是否被认为是不好的做法?也许是因为存在某种性能影响或增加了开销使用一个类而不是一堆函数会产生这种情况吗?

  2. 我一直计划让 WinMain 创建 Engine 实例作为局部变量。 Engine 类将相当大,包含用于渲染、脚本解析、文件系统内容等的类。基本上,除了操作系统特定代码之外,整个游戏引擎将以某种形式包含在 Engine 类中(可能作为实例)另一个类的。) 在 WinMain 函数中创建非常大的 Engine 类的本地实例是一个坏主意吗?当程序启动时创建类并在程序结束时结束时,创建本地实例是一个坏主意吗?也许new会更好?

  3. 我的计划(i/wa)将引擎划分为“模块”,每个模块都由一个类表示。 Engine 类将包含几乎所有其他模块的实例,例如上面提到的渲染、文件系统交互等。从某些角度(性能、设计、可读性?)

感谢您的帮助:)

I'm working on a lil' game engine in C++, and decided to do it all OOPily (heavy use of classes.)
It's intended to be (theoretically) cross-platform, so I have an 'Engine' class, an instance of which is created by the 'OS Module', which is WinMain for Windows (the platform I'm developing it for first.)

I have three main questions:

  1. Is it considered poor practice to create a class that is only going to be instantiated once in the entire application? Perhaps because there is some kind of performance hit or added overhead incurred by using a class rather than a bunch of functions?

  2. I've been planning to have WinMain create the instance of Engine as a local variable. The Engine class will be fairly large, containing classes for rendering, script parsing, file system stuff, etc. Basically, the whole game engine, apart from OS specific code, will be contained in the Engine class in some form (possibly as an instance of another class.) Is creating a local instance of my very large Engine class within the WinMain function a bad idea? Is creating a local instance a bad idea when the class will be created when the program starts, and end when the program ends? Maybe new would be better?

  3. My plan (i/wa)s to divide the engine up into 'modules', each of which is represented by a class. The Engine class would contain an instance of almost all the other modules, like, as mentioned above, rendering, file system interaction, etc. Is using classes as containers for huge modules a bad idea from some perspective (performance, design, readability?)

Thanks for any help :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

晨与橙与城 2024-11-20 06:11:08

游戏引擎不是跨平台的主要候选者,因为它们通常涉及与低级 API(不是跨平台)的有效交互。

类的大小取决于它包含的成员变量,而不是它实现的函数的数量。

堆栈空间通常很小 (http://msdn .microsoft.com/en-us/library/ms686774%28v=vs.85%29.aspx),理论上堆与可用 RAM 一样大。因此,如果您有非常大的东西,请将其存储在堆上(使用 new )。

“启动画面”:不要在程序开始时完成所有工作。用户讨厌当他们运行程序并且屏幕上没有显示任何内容时,因为您的程序正忙于初始化某些内容......
查找惰性实例化,基本上不做可以等待并始终在屏幕上显示某些内容的事情。

至于具体答案:
1. 不,假设没有虚函数,就不应该有性能开销。
2. 请参阅上面的“启动画面”和“有限的堆栈空间”。
3. 模块化通常很好,只需确保每个类确实/代表一个“事物”。但不要有太多的类,以至于你开始忘记它们的名称和用途:)

Game engines are not prime candidates for cross-platform'ness since they usually involve efficient interaction with low-level API's (which are not cross-platofrm).

The size of a class depends on the member variables it contains, not the number of functions it implements.

Stack space is usually small (http://msdn.microsoft.com/en-us/library/ms686774%28v=vs.85%29.aspx) while the heap is theoretically as big as available RAM. So, if you have something really big, store it on the heap (with new).

The "Splash Screen": don't do all the work at the beginning of the program. Users hate it when they run the program and nothing shows on screen because your program is busy initializing something...
Lookup lazy instantiation, basically don't do things that can wait and always show something on screen.

As for specific answers:
1. No, assuming no virtual functions, there should be no performance overhead.
2. See "Splash Screen" and "limited stack space" above.
3. Modularity is generally good, just make sure each class does/represent a single "thing". But don't have so many classes you start forgetting their names and purpose :)

像极了他 2024-11-20 06:11:08

这是否被认为是不好的做法
创建一个类,只会
在整个过程中被实例化一次
应用?也许是因为有
某种性能打击或增加
使用类产生的开销
而不是一堆函数?

一点也不。这基本上是因为您的 Application 类可以执行继承和封装等操作。不会影响性能或增加开销。

我一直计划拥有 WinMain
创建 Engine 的实例作为
局部变数。 Engine 类将
相当大,包含类
用于渲染、脚本解析、文件
系统的东西等等。基本上,
整个游戏引擎,除了操作系统
具体代码,将包含在
某种形式的 Engine 类
(可能作为另一个实例
类。)正在创建一个本地实例
我的非常大的引擎类
WinMain 函数是一个坏主意吗?是
创建本地实例是个坏主意
何时创建该类
程序开始,并在以下时间结束
程序结束?也许新的会是
更好吗?

不——这几乎是它应该走的路。为什么要麻烦堆分配呢?您需要自动销毁语义。除非您的类具有非常大的大小,数百 KB 或更多,在这种情况下,基于 RAII 的堆分配更智能,因为堆栈内存非常有限。也就是说,由 sizeof() 报告的每个实例的物理静态大小,不包括动态分配。

我的计划(i/wa)是分割引擎
进入“模块”,每个模块都是
由一个类来表示。发动机
类将包含一个实例
几乎所有其他模块,例如
上面提到的,渲染,文件
系统交互等正在使用
类作为巨大模块的容器
从某些角度来看是个坏主意
(性能、设计、可读性?)

这正是面向对象设计的目的——封装,将程序划分为明确定义的、独立的模块,然后实例化每个需要的模块,这正是面向对象编程的思想。类封装的概念的大小通常被认为是无关紧要的,只要它是一个单一的概念即可。清晰的模块化设计非常棒。

我建议对所有依赖于平台的类使用运行时继承,并且最好在运行时动态加载它们(使用操作系统类来执行动态加载)。这强制执行可靠的编译时抽象并允许更高效的编译。

Is it considered poor practice to
create a class that is only going to
be instantiated once in the entire
application? Perhaps because there is
some kind of performance hit or added
overhead incurred by using a class
rather than a bunch of functions?

Not at all. This is basically because your Application class can do things like inherit and encapsulate. There's no performance hit or added overhead.

I've been planning to have WinMain
create the instance of Engine as a
local variable. The Engine class will
be fairly large, containing classes
for rendering, script parsing, file
system stuff, etc. Basically, the
whole game engine, apart from OS
specific code, will be contained in
the Engine class in some form
(possibly as an instance of another
class.) Is creating a local instance
of my very large Engine class within
the WinMain function a bad idea? Is
creating a local instance a bad idea
when the class will be created when
the program starts, and end when the
program ends? Maybe new would be
better?

Nope- this is pretty much the way it should go. Why bother heap allocating? You want automatic destruction semantics. Unless your class has a very large size, hundreds of KB or more, in which case an RAII-based heap allocation is smarter, as stack memory is quite limited. That is, a physical per-instance static size as reported by sizeof(), not including dynamic allocations.

My plan (i/wa)s to divide the engine
up into 'modules', each of which is
represented by a class. The Engine
class would contain an instance of
almost all the other modules, like, as
mentioned above, rendering, file
system interaction, etc. Is using
classes as containers for huge modules
a bad idea from some perspective
(performance, design, readability?)

This is exactly what object-orientated design is for- encapsulation, and dividing the program up into clearly defined and separated modules, then instantiating each one that you need, is exactly the idea behind object-orientated programming. The size of the concept that a class encapsulates is usually considered to be irrelevant, as long as it's one single concept. A clear modular design is great.

I would recommend using run-time inheritance for all of the platform-dependent ones, and preferably, loading them dynamically at run-time (using the OS class to perform the dynamic loading). This enforces a solid compile-time abstraction and allows for more efficient compilation.

月亮是我掰弯的 2024-11-20 06:11:08
  1. 不,建议采取任何使您的设计更简洁、更易于维护的措施。
  2. 不,应尽可能避免直接使用免费存储(即,除非绝对必要,否则不要使用 new
  3. 请参阅 #1
  1. No, doing whatever makes your design cleaner and more maintainable is recommended.
  2. No, direct use of the freestore should be avoided whenever possible (i.e., don't use new unless you absolutely have to)
  3. See #1
几度春秋 2024-11-20 06:11:08
  1. 不,这并不被认为是不好的风格。事实上,我知道没有一个应用程序框架是没有它的,著名的单例模式基本上是围绕相同的主题(但不同,请注意)

  2. 我无法想象你的类实际上这么大。如果是,则将其放在堆上。然而,无论如何,该类的实际内容很可能都会位于堆上(我有点假设您将使用现有的容器类,100 个容器类中有 99 个会进行动态分配;这适用于 STL 容器,如下所示)好吧)

  3. 如果将它们放在数据段中,就像 auto 放在堆栈上或类的成员中一样,会有什么区别?我认为该课程强调模块化,并且可能使您能够更轻松地做事情(例如单元测试,或重用仅网络版本的引擎等)

  1. No it isn't considered bad style. In fact I know no application frameworks that go without one, and the renowned Singleton pattern is basically around the same theme (but different, mind you)

  2. I can't imagine that your class is actually that big. If it is, make it on the heap. However, chances are that the actual contents of that class are going to be on the heap anyway (I'm sort of assuming you'll use existing container classes, that wil 99 out of 100 do dynamic allocation; this goes for STL containers as well)

  3. What difference would it make whether you put them in the data segment, as auto's on the stack or members of a class? I think the class emphesizes the modularity and might enable you to do things more easily (like e.g. unit testing, or reusing the engine for a network-only version etc. etc.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文