包含层次结构中缺少类型 [英] missing types from a hierarchy of includes

查看:165
本文介绍了包含层次结构中缺少类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主题可能有点令人困惑,但这是正确的.我有一个所谓的头文件层次结构,所有这些头文件都具有支持该类的类,并且在传递信息方面有些困难.

我正在开发一个小型直接3d应用程序.代码被拆分,在这里我有一个名为Engine.h的头文件,然后现在,其中包含2个头文件Input.h和Graphics.h.在Engine.h的顶部,我有以下条目:

My subject may be a bit confusing, but it''s correct. I have what i would a call a hierarchy of header files, all with classes that support classes up the line, and I''m having some difficulty with the information being passed down.

I am working on a small direct 3d application. The code is split up, where i have a header file called Engine.h, and then for right now, 2 headers that are included in it, Input.h and Graphics.h . At the top of Engine.h I have this entry:

#include <Windows.h>

#include "Graphics.h"
#include "Input.h"



现在奇怪的是,在Input.h中定义的类中,它可以使用Windows类型,即HWND,但是由于某些原因,在尝试在Windows中使用HWND时,我会遇到有关缺少类型的错误我的Graphics.h文件.这是该文件:



Now the weird thing is here, in the class i have defined in Input.h , it is able to use windows types just fine, namely HWND, but for some reason i get an error about missing types when trying to use HWND in my Graphics.h file. here is that file:

#ifndef GRAPHICSCLASS
#define GRAPHICSCLASS

const bool VSYNC_DEPTH = true;
const float SCREEN_DEPTH = 1000.0f;
const float SCREEN_NEAR = 0.1f;

class GraphicsClass
{
public:
    GraphicsClass();
    ~GraphicsClass();

    bool Initialize(int, int, HWND);
    void Shutdown();
    bool Frame();

private:
    bool Render();

private:
};

#endif



尝试编译时收到的错误完全如下:



The error I receive when attempting to compile this is exactly as follows:

1>------ Build started: Project: engine, Configuration: Debug Win32 ------
1>  Graphics.cpp
1>c:\users\wyatt\documents\visual studio 2010\projects\engine\engine\graphics.h(15): error C2061: syntax error : identifier 'HWND'
1>c:\users\wyatt\documents\visual studio 2010\projects\engine\engine\graphics.cpp(14): error C2061: syntax error : identifier 'HWND'
1>  Generating Code...
1>  Compiling...
1>  Engine.cpp
1>  Generating Code...
1>  Compiling...
1>  EntryPoint.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



我只是假设此错误与找不到HWND类型有关,但是可能还有其他原因吗?任何帮助,将不胜感激. BTW,MSVC ++ Express.

这是Input.h文件:

Input.h



I just assume that this error has to do with it not finding the HWND type, but could it be something else? any help would be appreciated. BTW, MSVC++ express.

Here is the Input.h file:

Input.h

#ifndef _INPUTCLASS_H_
#define _INPUTCLASS_H_

#define DIRECTINPUT_VERSION 0x0800

#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

#include <dinput.h>


class InputClass
{
public:
	InputClass();
	~InputClass();

	bool Initialize(HINSTANCE, HWND, int, int);
	void Shutdown();
	bool Frame();
	bool IsEscapePressed();
	void GetMouseLocation(int &, int &);

private:
	bool ReadKeyboard();
	bool ReadMouse();
	void ProcessInput();

private:
	IDirectInput8* m_directInput;
	IDirectInputDevice8* m_keyboard;
	IDirectInputDevice8* m_mouse;

	unsigned char m_keyboardState[256];
	DIMOUSESTATE m_mouseState;
	
	int m_screenWidth, m_screenHeight;
	int m_mouseX, m_mouseY;
};

#endif

推荐答案

将Windows头文件包含在每个头文件中,因为它们是必需的.
因此,在Graphics.h文件中使用#include <WinDef.h>#include <Windows.h>.

要回答为什么Input.h可以在不包含#include< Windows.h>的情况下运行的情况:
您的Input.h文件包含dinput.h,该文件又包含objbase.h,该文件又包含许多其他头文件.在此头文件链中的某个点上,包含了定义HWND的头文件,因此,Input.h可以在不包含Windows.h的情况下工作. 但是,不应依赖于此,最好的做法是在Input.h文件中也包含#include <WinDef.h>#include <Windows.h>.

多次包含Windows.h:
这不是问题,文件包含预处理程序指令 [ ^ ],以确保实际上仅包含一次.
Include the windows header files in each of your headers files as they are needed.
So use #include <WinDef.h> or #include <Windows.h> in your Graphics.h file.

To answer why Input.h does work without including #include <Windows.h>:
Your Input.h file includes dinput.h, which in turn includes objbase.h, which in turn includes many other header files. At some point in this chain of headers the header that defines HWND is included, hence the fact that Input.h works without including Windows.h.
This should not be relied on though and it is better practice to also include #include <WinDef.h> or #include <Windows.h> in your Input.h file.

Include Windows.h multiple time:
This is not a problem, the file contains preprocessor directives[^] that ensure it is actually included only once.
#ifndef _GNU_H_WINDOWS_H
#define _GNU_H_WINDOWS_H
..
#endif /* _GNU_H_WINDOWS_H */


在解决问题的同时,这里提供了一些解决问题的建议这种类型(并改善您对#include语句的使用):

对于引起问题的任何标头,请执行以下操作:
1.创建一个.cpp文件,该文件只包含对该头文件的#include语句(如果使用一个,则还包括对预编译头文件的包含)
2.删除头文件中的所有#include语句(或将其注释掉,以后可能需要使用它们)
3.编译您的.cpp文件
4.查看编译器的文本输出并找到第一条错误消息;它可能会抱怨一些未知符号".
5.a)如果没有更多未知符号"消息,则说明您已完成该标头的操作!
5.b)如果存在未知的符号消息,请使用前向声明查看是否可以不使用它;如果不是,请查看该符号所需的包含文件的文档,并为此添加一个#include.然后继续3.

我无法承受太多压力,您需要检查文档(或让熟悉该库的人)找到要包括的正确头文件.通常,您不希望直接包含一个包含定义的文件,而是一个包含(或包含)该定义可能需要的相关内容的文件. (这种依赖关系不应该存在,但是不幸的是,它们确实存在.上面概述的算法的要点是避免在您自己的标头中使用这种依赖关系.)

当您处理完所有有问题的标头后,对由于符号未知而无法编译的任何.cpp文件执行相同的操作:步骤2至5,仅这次不使用前向声明. >
这可能会花费一些时间,但是它将消除标头之间的问题依赖性,尤其是那些要求您按特定顺序包括标头的标头,并且可能会减少构建时间. (我曾经花了一周的大部分时间来清理大型项目中的此类依赖,最终将编译时间减少到三分之一!)
While your problem is solved, here is some advice how to tackle problem of this type (and improve your use of #include statements):

For any header causing a problem do the following:
1. Create a .cpp file that contains nothing but an #include statement to that header (plus maybe an include to the precompiled header, if you use one)
2. remove all #include statements in your header file (or comment them out, you might need them later)
3. compile your .cpp file
4. look at the text output of your compiler and find the first error message; it might complain about some ''unknown symbol''.
5.a) If there is no more ''unknown symbol'' message your done with that header!
5.b) If there is an unkown symbol message, see if you can work without it, using a forward declaration; if not, check the documentation which include file you need for that symbol, and add an #include for that. Then continue with 3.

I can''t stress enough that you check the documentation (or ask someone familiar with the library) to find the right header file to include. Often you will not want to directly include the one file that contains the definition, but one that contains (or includes) some related stuff as well which may be required for that definition. (Such dependencies shouldn''t exist, but unfortunately they do. The main point of the algorithm outlined above is to avoid such dependencies in your own headers.)

When you''re done with all offending headers, do the same with any .cpp file that won''t compile due to unknown symbols: steps 2. to 5, only this time don''t use forward declarations.

This may take quite some time, but it will remove problematic dependencies between your headers, especially those that require you to include them in specific order, and it might reduce your build time. (I once spent the better part of a week to clean up such dependencies in a large project, and in the end the compile time was reduced to a third!)


这篇关于包含层次结构中缺少类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆