头部防护/翻译单元问题

时间:2011-09-27 08:13:38

标签: c++

我认为标题保护解决了重新定义的问题。我收到链接器错误,说明.obj文件中有重新定义。这是我所包含的标题,问题在于重新定义所有全局声明。

#ifndef DIRECT3D_H
#define DIRECT3D_H

// global declarations
ID3D10Device* device;
ID3D10Buffer* pBuffer;
ID3D10Buffer* iBuffer;    // the pointer to the index buffer
ID3D10RenderTargetView* rtv;    // the pointer to the render target view
ID3D10DepthStencilView* dsv;    // the pointer to the depth stencil view
IDXGISwapChain* swapchain;    // the pointer to the swap chain class
ID3D10Effect* pEffect;
ID3D10EffectTechnique* pTechnique;
ID3D10EffectPass* pPass;
ID3D10InputLayout* pVertexLayout;
ID3D10EffectMatrixVariable* pTransform;    // the pointer to the effect variable interface
D3D10_PASS_DESC PassDesc;

// function prototypes
void initD3D(HWND hWnd);
void render_frame();
void init_pipeline();
void cleanD3D();
void Init();

#endif

说这个标题叫做3DClass.h。它包含在3DClass.cpp中。它也包含在另一个文件中 - 一个主要的游戏循环。现在,我意识到当有多个翻译单元时头文件可能存在问题,但我不太明白为什么这不起作用,我只将头包含在一个文件中,也包含在相应的源文件中。这不应该没事吗?

2 个答案:

答案 0 :(得分:8)

标题保护解决了包括相同标题两次或隐藏递归包含的问题,而不是双重定义。

如果您在不同的翻译单元中包含相同的标题,则标题保护将无济于事。

解决方案是从不在头文件中声明变量。如果您需要共享变量,请在标题中使用extern关键字,并在翻译单元的 one 中声明实际变量。

答案 1 :(得分:2)

标题保护只能防止头文件的保护部分被包含两次。结果传递给编译器,因此编译器不知道任何标头保护。

因此,它将为包含标题的每个翻译单元发出这些符号(因为它无法知道在某处编译了另一个不相关的翻译单元)。

此外,链接器也无法知道您不希望发生这种情况。

要解决此问题,请在标题中声明变量extern,并在一个单独的翻译单元中定义它们。