Visual Studio 2012 Express 编译器未正确链接头文件

Visual Studio 2012 Express compiler not linking header files together correctly

本文关键字:链接 文件 Studio 2012 Express 编译器 Visual      更新时间:2023-10-16

我正在为一个小的2D游戏设置一些框架。现在,我只有几个类,但我立即陷入编译器问题。

我只用main功能运行了这个程序,所以我可以确认 Allegro(图形库)库链接是否有效。

我已将所有头文件 (.h) 放在解决方案资源管理器的"头文件"部分下,将所有源文件 (.cpp) 放在"源文件"部分。我只修改了默认设置,根据这个 Allegro 教程:http://wiki.allegro.cc/index.php?title=Windows,_Visual_Studio_2010_and_Allegro_5。它不应该以破坏性的方式影响任何事情。

我有几个文件,所以我会列出每个文件。我将跳过一些代码以减少大小和冗余。当我省略任何代码或做任何不逐字逐句的事情时,我会在代码中加入注释。(编辑:我实际上没有跳过任何代码)

主.cpp

#include "common.h"
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
World* world = new World(640, 480);
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!n");
return -1;
}
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!n");
return -1;
}
al_clear_to_color(al_map_rgb(0,0,0));
world->draw(display);
al_flip_display();
al_rest(10.0);
al_destroy_display(display);
return 0;
}

普通.h

#if !defined(COMMON_INC)
#define COMMON_INC
#include "World.h"
#include "Pane.h"
#include <stdio.h>
#include <allegro5/allegro.h>
#endif

世界.h

#if !defined(WORLD_INC)
#define WORLD_INC
#include "common.h"
#include "Pane.h"
class World{
public:
World(int wp, int hp);
void draw(ALLEGRO_DISPLAY* display);
void update();

protected:
private:
Pane* panel;
int heightPix, widthPix;
};
#endif

世界.cpp

#include "common.h"
World::World(int wp, int hp){
widthPix = wp;
heightPix = hp;
panel = new Pane(this, 10, 10, 300, 400);
return;
}
void World::draw(ALLEGRO_DISPLAY* display){
panel->draw(display);
return;
}

窗格.h

#if !defined(PANE_INC)
#define PANE_INC
#include "common.h"
class Pane{
public:
Pane(World* w, int xv, int yv, int wi, int he);
World* getWorld();
int getZ();
void draw(ALLEGRO_DISPLAY* display);
ALLEGRO_BITMAP* getBackground();
protected:
void setXY(int xv, int yv);
void setWidthHeight(int wi, int he);
void setZ(int zv);
void setBackground(ALLEGRO_BITMAP* ba);
private:
int z;
int x, y; //pixels
int width, height; //pixels
World* world;
ALLEGRO_BITMAP* background;
};
#endif

窗格.cpp

#include "common.h"
Pane::Pane(World* w, int xv, int yv, int wi, int he){
this->setWidthHeight(wi, he);
this->setXY(xv, yv);
this->world = w;
}
World* Pane::getWorld(){
return world;
}
void Pane::setXY(int xv, int yv){
x = xv;
y = yv;
return;
}
void Pane::setWidthHeight(int wi, int he){
width = wi;
height = he;
return;
}
void Pane::setZ(int zv){
z = zv;
return;
}
void Pane::draw(ALLEGRO_DISPLAY* display){
if(background != NULL)
al_draw_bitmap(background, x, y, 0);
else{
background = al_create_bitmap(width, height);
al_set_target_bitmap(background);
al_clear_to_color(al_map_rgb(255, 0, 255));
al_set_target_bitmap(al_get_backbuffer(display));
al_draw_bitmap(background, x, y, 0);
}
return;
}

编译器在构建时生成此错误报告:(我称该游戏为疯狂科学家,因为它应该是炼金术主题)

1>------ Build started: Project: MadScientist, Configuration: Debug Win32 ------
1>  main.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(8): error C2061: syntax error : identifier 'World'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(11): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): warning C4183: 'getBackground': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(18): error C2061: syntax error : identifier 'ALLEGRO_BITMAP'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(24): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(24): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(10): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistmain.cpp(22): error C2660: 'World::draw' : function does not take 1 arguments
1>  World.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(8): error C2061: syntax error : identifier 'World'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(11): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): warning C4183: 'getBackground': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(18): error C2061: syntax error : identifier 'ALLEGRO_BITMAP'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(24): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(24): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(10): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.cpp(6): error C2661: 'Pane::Pane' : no overloaded function takes 5 arguments
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.cpp(10): error C2511: 'void World::draw(ALLEGRO_DISPLAY *)' : overloaded member function not found in 'World'
1>          c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(7) : see declaration of 'World'
1>  Pane.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(8): error C2061: syntax error : identifier 'World'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(11): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(12): warning C4183: 'getBackground': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(18): error C2061: syntax error : identifier 'ALLEGRO_BITMAP'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(24): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(24): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(10): error C2061: syntax error : identifier 'ALLEGRO_DISPLAY'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.cpp(3): error C2511: 'Pane::Pane(World *,int,int,int,int)' : overloaded member function not found in 'Pane'
1>          c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(6) : see declaration of 'Pane'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.cpp(9): error C2556: 'World *Pane::getWorld(void)' : overloaded function differs only by return type from 'int *Pane::getWorld(void)'
1>          c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9) : see declaration of 'Pane::getWorld'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.cpp(9): error C2371: 'Pane::getWorld' : redefinition; different basic types
1>          c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9) : see declaration of 'Pane::getWorld'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.cpp(10): error C2065: 'world' : undeclared identifier
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.cpp(30): error C2511: 'void Pane::draw(ALLEGRO_DISPLAY *)' : overloaded member function not found in 'Pane'
1>          c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(6) : see declaration of 'Pane'
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

你有我所做的所有信息。我将为您总结一下,以省去浏览所有内容的麻烦。

  • 将类分为标头接口和源实现
  • common.h 包含在所有文件中。它本身包括其他头文件中的所有类定义
  • 编译时,编译器不会将其他头文件中定义的类识别为数据类型。正如您所料,错误会级联下来。
  • 实时错误检查器不会记录任何错误。例如,当将鼠标悬停在单词"World"上时,当它用作Pane中的数据类型时,它可以完美地识别该类型。实时错误检查器是在编译器时间之前用红色标记错误的功能。
  • 这个Visual Studio 2012 Express是新的,除了前面提到的修改。该项目是作为空C++项目创建的。在添加许多标头和源之前,main函数正确编译。

感谢您的任何回复。如果您有任何问题,请提问。我在Visual Studio上遇到的问题总是让我感到恼火。

编辑:

我的循环标头逻辑由标头保护器保护。我不认为这种冗余是一个问题。

我尝试从头文件中删除除 Allegro 库的包含之外的所有包含。这似乎效果更好,但仍然存在奇怪的问题。为什么包含的行为会导致这些数据类型出错仍然是一个谜。以下是新的错误日志:

1>------ Build started: Project: MadScientist, Configuration: Debug Win32 ------
1>  main.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  World.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.cpp(6): error C2065: 'panel' : undeclared identifier
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.cpp(11): error C2065: 'panel' : undeclared identifier
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.cpp(11): error C2227: left of '->draw' must point to class/struct/union/generic type
1>          type is ''unknown-type''
1>  Pane.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

第 2 轮编辑:

我切换了我的代码,所以common.h只包括stdio和Allegro。所有头文件和源文件都包括 common.h,然后是它们单独使用的任何类的头文件。窗格.cpp包括 Pane.h 和 common.h。World.h 包括 Pane.h 和 common.h。

错误日志显示:

1>------ Build started: Project: MadScientist, Configuration: Debug Win32 ------
1>  main.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C2061: syntax error : identifier 'World'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(10): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(10): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  World.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(9): error C2061: syntax error : identifier 'World'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(10): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(10): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(10): warning C4183: 'getWorld': missing return type; assumed to be a member function returning 'int'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistpane.h(25): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.cpp(7): error C2661: 'Pane::Pane' : no overloaded function takes 5 arguments
1>  Pane.cpp
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C2143: syntax error : missing ';' before '*'
1>c:usersethomadocumentsvisual studio 2012projectsmadscientistmadscientistworld.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

这就是我现在如何看待我的包含订单:

  1. 主要包括常见
  2. 通用定义COMMON_INC
  3. 常见的包括 STDIO 和 Allegro
  4. 主要包括世界。
  5. 世界定义WORLD_INC
  6. 世界包括共同,这是被阻止的。但这应该没问题,因为已经包含通用
  7. 世界包括窗格
  8. 窗格定义PANE_INC
  9. 窗格包括 common,它被阻止。但这应该没问题,因为已经包含通用。
  10. 窗格包括世界。这被阻止了,因为主要已经包括了世界。这不应该没问题,因为世界已经包括在内。如果我需要多次包含文件,为什么我什至有编译器保护,每个使用它的文件一次?

编辑第 3 轮:我从这里的答案和评论中学到了很多东西。事实证明,根据维基百科,"循环依赖通常是由缺乏经验的程序员引入的,他们需要实现某种回调功能。Pane使用World和World使用Pane这一事实本身就是一个设计缺陷。在Java中,这对我来说都很好。这很容易;我认为这是通知"拥有"对象的实体对象操作的最佳方式。

事实证明,这是一个糟糕的设计方案。对象不应依赖于其"拥有者"。相反,我需要实现一个观察者系统,其中窗格可以告诉世界它已经更新了它的状态。

阅读维基百科清除了我的任何问题,所以我现在认为这个问题已经完成。感谢贡献者为学习程序员提供

您的头文件无法正确链接。您以循环方式包含标题。头文件包含common.h,而common.h又包含其他头文件,如World.hPane.h

这不能由任何编译器编译。您必须开发从低级标头到高级标头的标头层次结构,并确保较高级别标头仅包含较低级别的标头。这样,您将确保您没有圆形夹杂物。

无论如何,为什么你的common.h包括World.hPane.h?这看起来像一个明显的错误。common.h旨在成为低级标头。让World.hPane.h包含它,但不要将World.hPane.h包含在common.h中。

请注意,在这种情况下,标头保护不能解决任何问题。他们只是确保包含周期不会变得无限。它们打破了循环,但它们不能帮助您解决声明之间的循环依赖关系(如果存在此类依赖关系)。

看看处理main.cpp时您的情况会发生什么

  1. main.cpp包括common.h
  2. common.h定义COMMON_INC
  3. common.h包括World.h
  4. World.h定义WORLD_INC
  5. World.h包括common.h包含守卫跳过了整个common.h,因为COMMON_INC是在步骤 2 中定义的。
  6. World.h包括Pane.h
  7. Pane.h定义PANE_INC
  8. Pane.h包括common.h包含守卫跳过了整个common.h,因为COMMON_INC是在步骤 2 中定义的。
  9. Pane.h称为类型WorldWorld型是未知的,因为我们还没有在World.h中得到它的定义。错误!

我认为即使您进行以下更改,即使使用循环包含,所有内容也会编译

  1. common.h中,您需要重新排列标题的顺序。

    #include <allegro5/allegro.h>
    #include "World.h"
    #include "Pane.h"
    #include <stdio.h>
    
  2. pane.h中,在#include common.h之后,添加一个前向声明,用于class World

    #include "common.h"
    class World;
    class Pane{
    .....
    

我认为这将使您的错误消失或至少大大减少它们。 我的答案是基于你提出的原始代码,而不是编辑。