【发布时间】:2019-04-29 13:14:27
【问题描述】:
我正在考虑创建一个新的大型 C++ 项目。开始很容易 - 只是一个简单的窗口,可能是 SDL2,可能是 SFML,甚至可能是 WIN32。嗯,我应该拿什么?使用我想要的任何窗口不是更好吗?不用修改太多代码让其他类独立于这个窗口?
说完了!使用简单的窗口界面,每个类都知道像窗口这样的东西,我可以在不同的类型之间进行选择。唯一的要求是将 IWindow 作为基类。
class IWindow {
public:
IWindow(std::string title, int posX, int posY, int width, int height);
IWindow getHandle();
void loop();
bool toggleFullscreen();
bool toggleFullscreen(bool fullscreen);
int getWidth();
int getHeight();
int getPosX();
int getPosY();
//And so on ...
};
但是现在,由于我必须使用虚拟方法,所以每次我的虚拟函数循环都会被游戏循环调用。并且虚函数更慢。大约 10%,我读过。
编译器不能看到我的窗口是什么吗?它将来自哪种类型?难道它看不到“Jeah,这个程序员在这个应用程序中创建了一个 SDL 窗口,所以在任何地方都使用它的方法。”?我的意思是,我在主循环期间定义我的窗口,它永远不会改变。这不是动态的。这是可以预见的。
那么编译器是否能够优化我的可预测虚函数调用?这些将在每个游戏循环周期中进行评估?就像下面这段话一样?
int main(int argc, char* argv[]) {
//Creates a window derived from IWindow
SDL::Window myWindow("Title", 0, 0, 300, 100);
//Storing it as IWindow in a wrapper class
Game myGame(&myWindow);
//Game loop
//myGame.run() calls the window's loop
while (myGame.run()) {
//... doing game stuff
}
}
使用这样的游戏类:
class Game {
protected:
IWindow* window;
public:
bool run() {
//Calls the window's virtual loop method.
//Will it be optimized? Any way to do so?
this->window->loop();
}
};
很高兴听到您的想法和经验。
达斯月亮
【问题讨论】:
-
如果编译器可以确定你的对象是给定类型的,那么它可以去虚拟化。但在你的第二种情况下,不,它不能。不过,TLB 将能够预测它,因此您不会因为预测保留在其表中而承担全部成本。
-
TLB?什么意思?
-
对于第一种情况(
main),是的,它可以去虚拟化。第二,它很可能不能。由于IWindow是一个高级对象,我不会担心这一点。 -
@DarthMoon 不,您的游戏不需要尽可能快。可能有大约 0 个程序尽可能快。
-
@DarthMoon:这几乎不会花费您任何费用,这就是原因。一个简单的 getter 内联函数会比一个虚函数的成本低很多(对于一个简单的 getter 函数,它不仅仅是 10%,而是更多),这是毫无疑问的。但是,如果这个函数只被调用~10 次/帧,那么就没有关系了。
标签: c++ inheritance code-generation compiler-optimization virtual-functions