头文件中出现奇怪的VS++语法错误?(SDL2相关)

Weird VS++ syntax errors in header file? (SDL2 Related)

本文关键字:错误 语法 SDL2 相关 VS++ 文件      更新时间:2023-10-16

所以我最近尝试清理我的代码,试图让它对我自己(以及其他人(如果需要的话))更容易。

现在,这可能是因为我对整个C++有点陌生(尽管我在Java方面还有几年的经验)。但我听说(更像是读到的)在头文件中包含头是个坏主意,因为这会让程序的其他部分陷入困境,让事情变得头疼(事实上,我遇到过一些问题,我只需要在".cpp"文件中包含一个头,而且它(显然)包含了我需要的所有内容)。

所以我决定对我的标题做以下操作:

#pragma once
class Game {
(...)
public:
    SDL_Window* getPrimaryWindow(void) const;
    SDL_Renderer* getPrimaryRenderer(void) const;
    SDL_Surface* getPrimarySurface(void) const;
(...)
private:
    SDL_Window* mp_primaryWindow = 0;
    SDL_Renderer* mp_primaryRenderer = 0;
    SDL_Surface* mp_primarySurface = 0;
};

因此,我没有在".hpp"文件中包含任何头,而是在".cpp"文件内。现在,在这两个文件中都不会触发intellisense错误。。。"一切都好"我想。将鼠标悬停在每个变量上,会显示以下内容:

SDL_Window *Game::mp_primaryWindow

如果我把鼠标悬停在类型上:

struct SDL_Window
*brief The Type used to identify a window
(...)

SDL_Renderer和SDL_Surface也是如此。。。一切都很好。

现在,我试着构建这个项目。。。这就是一切走向地狱的地方,并向我抛出以下错误:

error C2143: syntax error: missing ';' before '*'
error C2238: unexpected token(s) preceding ';'
error C4430: missing type specifier - int assumed. Note C++
does not support default-int

所以,那根本没有好处。但是,如果我将#include <SDL.h>添加到顶部,它的编译和构建都很好。

有人能解释一下发生了什么,为什么会发生,如果我必须回到我的代码中,把所有的include都放回我的头中吗?

是的,当不需要在头中包含头时,应该避免在头中包括头。但是,如果在标头中使用非内置类型,则需要包含定义该类型的标头(将其包含在该标头中),或者需要转发声明该类型。正向声明通常是这样的,尽管它们可能会根据正向声明的类型而有所不同:"class CWindow;",并位于文件的顶部。只有当您有指向类型的指针或引用,但类中没有实际对象,或者实际对象作为参数传递给头中的函数时,正向声明才有效。

请注意,在头中包含头对于编译时间来说大多是不好的。如果你的程序编译不太慢,不要紧张——只要在你的头中包含头,一切都会好起来的。

实际上,有一种情况下,你应该顺便在你的头中包含头。基本上,如果您在页眉中使用某个类"CSomeClass",您可以要求包含页眉的CPP文件在页眉之前也包含"CSomeClass.h",但这会给使用您的类的人带来额外的负担。头文件应该是自包含的,并且应该包括它所需要的所有类型的头,或者应该转发声明它们。

希望能有所帮助!Java和C++在日常使用中有很大不同(: