头文件很有用,很多函数都需要一个位置来共用声明(不是定义,定义只能定义一次)。

工程中有两个cpp文件

main.cpp

#include<iostream>

void Log(const char* message)
{
    std::cout<<message<<std::endl;
}

int main()
{
    Log("Hello world!");
    std::cin.get();
}

Log.cpp

void InitLog()
{
    Log("Initializing Log");
}

ctrl+F7编译main.cpp不会出错,但是编译Log.cpp会报错,因为Log函数不存在,所以Log.cpp需要什么东西才不会报错,应该怎样告诉他Log函数存在只是在别的文件中?这就需要用到函数声明。因此加上声明编译就不再报错。

void Log(const char* message);

void InitLog()
{
    Log("Initializing Log");
}

如果我创立了其他的cpp文件,又要用到Log函数,那么我需要将Log函数的声明再次复制粘贴到其他的cpp文件中。将声明放进头文件中可以简化这个操作,因为include本质就是将头文件的内容直接粘贴到include的位置上。

Log.h

#pragma once

void Log(const char* message);

Log.cpp

#include"Log.h"
void
InitLog() { Log("Initializing Log"); }

main.cpp不变,将Log.h include进来也没什么问题。如果我想在main.cpp中调用InitLog函数,那么我需要声明他,同样可以将声明加入到头文件中

Log.h

#pragma once

void Log(const char* message);
void InitLog();

Log.cpp

#include<iostream>
#include"Log.h"

void InitLog()
{
    Log("Initializing Log");
}

void Log(const char* message)
{
    std::cout<<message<<std::endl;
}

main.cpp

#include<iostream>
#include"Log.h"

int main()
{
    InitLog();
    Log("Hello world!");
    std::cin.get();
}

头文件_头文件

 

 

 #pragma once是什么意思

首先以"#"开头是预处理命令,pragma once的意思时这个文件只include一次,被称为头文件保护符,防止我们将一个头文件多次include到一个cpp文件中。

Log.h

//#pragma once

void Log(const char* message);
void InitLog();

struct player{};

将#pragma once注释掉,然后在Log.cpp中include Log.h两次

#include<iostream>
#include"Log.h"
#include"Log.h"

void InitLog()
{
    Log("Initializing Log");
}

void Log(const char* message)
{
    std::cout<<message<<std::endl;
}

编译时会发现struct player被重定义,报错。

如果建立一个新的头文件common.h来对其他头文件进行统一引用

#pragma once
#include"Log.h"

然后将Log.h中的#pragma once注释掉

这个时候如果在Log.cpp中同时include Log.h和common.h,仍或出现struct player被重定义的错误,因为缺少#pragma once,Log.h被引用两次,导致struct player被重定义。如果取消注释#pragma once,那么会顺利编译,因为#pragma once保证了Log.h只被include一次。另外一种头文件保护是用#ifndef

#ifndef _LOG_H
#define _LOG_H

void Log(const char* message);
void InitLog();

struct player{};

#endif

他要做的时先检查Log h这个符号是否存在,如果没有定义,以下代码将会加入到include中,如果定义了那么这些都不会被include,全部被禁用。最简单的办法是将上面的代码直接复制到cpp文件中

#include<iostream>
#include"Common.h"
#include"Log.h"

#ifndef _LOG_H
#define _LOG_H

void Log(const char* message);
void InitLog();

struct player{};

#endif

void InitLog()
{
    Log("Initializing Log");
}

void Log(const char* message)
{
    std::cout<<message<<std::endl;
}

如果将Common.h和Log.h全部注释掉,代码也不会出错,因为没有检测到log h就将这些定义进去。这种头文件保护符在过去更长荣,现在有了#pragma once后大多使用#pragma once