向前声明一个结构时出错:"这里有一个先前的声明"

voi*_*Foo 5 c++

在构建我的小型C++项目时,我得到以下2个错误,无法找出原因:

  • 错误:在'struct'之后使用typedef-name'TTF_Font'.
    指向以下代码行:struct TTF_Font;在Foo.h中.

  • 错误:'TTF_Font'在此处有一个先前的声明.
    指向以下代码行:typedef struct _TTF_Font TTF_Font;在SDL_ttf.h中.

我已将其缩小到新测试项目中的以下文件:

foo.h中:

#ifndef FOO_H
#define FOO_H

struct TTF_Font;

class Foo
{
    TTF_Font* font;
};

#endif // FOO_H
Run Code Online (Sandbox Code Playgroud)

Foo.cpp中:

#include "Foo.h"
#include "SDL/SDL_ttf.h"

// No implementation, just testing
Run Code Online (Sandbox Code Playgroud)

Main.cpp的:

#include "Foo.h"
int main(int argc, const char* argv[])
{
    Foo a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

你们知道我做错了吗?

我的目标是转发声明TTF_Font,所以我可以在我的头文件中使用它而不包括SDL_ttf头文件.我读到包含其他头文件中的头文件是一种不好的做法,所以我切换到转发声明.我的所有其他前向声明工作正常,除了这个单一的结构.

当我用struct TTF_Font;标题include 替换前向声明时#include "SDL/SDL.ttf.h",它编译没有错误.所以我可以使用它,但我想知道为什么,该死的:-).

额外信息:我正在使用Code :: Blocks IDE和mingw32编译器.Project使用SDL图形库.还没有太多的C++经验,来自C#背景.

CB *_*ley 8

您试图将某些内容声明为与实际不同的类型.

你宣布:

struct TTF_Font;
Run Code Online (Sandbox Code Playgroud)

当错误消息表明TTF_Font实际上是a时typedef,而不是struct:

typedef struct _TTF_Font TTF_Font;
Run Code Online (Sandbox Code Playgroud)

这个结果实际上被称为_TTF_Font.

您可以typedef多次声明相同,因此您可以使用typedef声明而不是前向声明来声明struct和引入typedef虽然它确实感觉有点像您正在使用您尝试推迟的标头的实现细节,包括.

  • 谢谢!当我使用头文件中的相同typedef行时,它可以正常工作,但就像你已经提到它有点使用SDL_ttf头文件的细节.这种事情有最好的做法吗?我应该省略前向声明,只是在这样的情况下包含头文件? (2认同)
  • @void_Foo:通常,包括头文件是最安全的选项.如果有一种可接受的方式来转发从库或"仅声明"头文件中声明某些东西,那么库文档应该指出这一点. (2认同)