有人可以帮助澄清头文件的工作原理吗? [英] Can someone help clarify how header files work?

查看:127
本文介绍了有人可以帮助澄清头文件的工作原理吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我一直在使用C ++几个星期,但头文件(或者我认为的连接器)背后的机制混淆了我。我习惯于创建一个main.h来对其他头文件进行分组,并保持main.cpp整洁,但有时候这些头文件会抱怨无法找到不同的头文件(尽管它已被声明在main.h中)。我可能没有解释得很好,所以这是我试图做的一个删节版本:

  // main .cpp 

#includemain.h
int main(){
return 0;

-

 // main.h 

#includeplayer.h
#includehealth.h
#includecustvector.h

-

  // player.h 

#includemain.h
class Player {
private:
Vector playerPos;
public:
健康playerHealth;
};

-

  // custvector.h 

结构向量{
int X;
int Y;
int Z;
};

-

  // health.h 
class Health {
private:
int curHealth;
int maxHealth;
public:
int getHealth()const;
void setHealth(int inH);
void modHealth(int inHM);
};

我不包含health.cpp,因为它有点冗长(但确实有效)编译器(Code :: Blocks)抱怨说编译器(Code :: Blocks) player.h找不到'Health'或'Vector'类型。我认为如果我在中使用了 #includemain.h,它可以找到 Health Vector 感觉它们包含在main.h中。我想他们会想他们通过隧道(player.h - > main.h - > health.h)。但那不太好。是否有某种图表或视频可以阐明如何设置?谷歌没有太大的帮助(也没有我的书)。

解决方案

这里的其他答案有效地解释了头文件和预处理工作。你所面临的最大问题是循环依赖,从经验来看,我知道这可能是一种皇室的痛苦。而且,当这种情况发生时,编译器开始以非常奇怪的方式运行,并抛出错误消息,这些消息不是非常有用。我在大学里被一位C ++大师教过的方法是用每一个文件(例如头文件)来开始每一个文件,其中包含

$ p $ //文件的开头部分
#ifndef HEADER_FILE_H //使用一个独特的名字!
#define HEADER_FILE_H
...
//代码在这里
...
#endif
//文件的最后部分

这使用预处理器指令来自动防止循环依赖。基本上,我总是使用全部大写的文件名。 custom-vector.h 变成

  #ifndef CUSTOM_VECTOR_H 
#define CUSTOM_VECTOR_H

这允许您在不创建循环依赖的情况下包含文件willie-nillie,因为如果文件是包括多次,其预处理器变量已经定义,所以预处理器跳过该文件。这也使得后来更容易处理代码,因为您不必筛选旧的头文件以确保您没有包含某些内容。我会再次重复一遍,确保您在 #define 语句中使用的变量名对您是唯一的,否则您可能会遇到某些问题无法正确包含; - )。



祝你好运!


I've been working with C++ for a good couple of weeks now, but the mechanism behind header files (or the linker I suppose?) confuses the heck out of me. I've gotten in the habit of creating a "main.h" to group my other header files and keep the main.cpp tidy, but sometimes those header files complain about not being able to find a different header file (even though it's declared in the "main.h"). I'm probably not explaining it very well so here's an abridged version of what I'm trying to do:

//main.cpp

#include "main.h"
int main() {
    return 0;
}

-

//main.h

#include "player.h"
#include "health.h"
#include "custvector.h"

-

//player.h

#include "main.h"
class Player {
    private:
        Vector playerPos;
    public:
        Health playerHealth;
};

-

//custvector.h

struct Vector {
   int X;
   int Y;
   int Z;
};

-

//health.h
class Health {
    private:
        int curHealth;
        int maxHealth;
    public:
        int getHealth() const;
        void setHealth(int inH);
        void modHealth(int inHM);
};

I won't include health.cpp because it's a bit lengthy (but does work), it does have #include "health.h".

Anyways, the compiler (Code::Blocks) complains that "player.h" can't find the types 'Health' or 'Vector'. I thought that if I used #include "main.h" into "player.h" it would be able to find the definitions for Health and Vector sense they're included in "main.h". I figured they would they would sort of tunnel their way though (player.h -> main.h -> health.h). But that didn't work too well. Is there some kind of a diagram or video that could clarify how this should be set up? Google wasn't much help (nor my book).

解决方案

The other answers here have effectively explained the way header files and the preprocessor work. The biggest problem you have is the circular dependencies, which from experience, I know can be a royal pain. Also, when that starts happening, the compiler starts to behave in very odd ways and throw error messages that aren't super helpful. The method I was taught by a C++ guru in college was to start each file (a header file for instance) with

//very beginning of the file
#ifndef HEADER_FILE_H //use a name that is unique though!!
#define HEADER_FILE_H
...
//code goes here
...
#endif
//very end of the file

This uses preprocessor directives to automatically prevent circular dependencies. Basically, I always use an all uppercase version of the file name. custom-vector.h becomes

#ifndef CUSTOM_VECTOR_H
#define CUSTOM_VECTOR_H

This allows you to include files willie-nillie without creating circular dependencies because if a file is included multiple times, its preprocessor variable is already defined, so the preprocessor skips the file. It also makes it easier later on to work with the code because you don't have to sift through your old header files to make sure you haven't already included something. I'll repeat again though, make sure the variable names you use in your #define statements are unique for you otherwise you could run into problems where something doesn't get included properly ;-).

Good luck!

这篇关于有人可以帮助澄清头文件的工作原理吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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