头文件是否没有被编译(C++ Visual Studio 2015)

3
只是为了测试是否可行(我知道这种做法很糟糕),我在头文件中完全定义了一个函数,并在主cpp文件中进行了相应的前向声明。C ++函数不需要在它们被使用的翻译单元中进行定义,因此头文件几乎完全只包含前向声明(除了内联函数)。但是,当我尝试编译这个项目时,它说有未解决的外部引用。
当我将头文件的全部内容移到源文件中(同时删除头文件),它就可以编译并按预期执行。那么,头文件在构建项目时就不能被编译吗,还是有一些我不知道的例外?
此外,即使我只是在属性浏览器中转到头文件的属性并将其“文件类型”设置为“C / C ++代码”,并将其扩展名更改为.cpp,它仍然无法编译(即使如果我只是删除它并创建一个新的源文件,它仍然可以编译,我认为这是最奇怪的部分)。
(我正在使用禁用扩展/Za,如果有变化,请注意)
以下是代码文件:
//main.cpp
void foo();

void main()
{
    foo();
}

以及头文件

//test.h
#include <iostream>

void foo()
{
    std::cout << 'a';
}

3
除非通过 #include 预处理将其引入到翻译单元中,否则头文件不会被编译。由于您唯一的 .cpp 文件没有这样的包含,它不会被编译,因此其中的任何内容对该翻译单元(显然是您唯一的翻译单元)都不可用。 - WhozCraig
http://faculty.cs.niu.edu/~mcmahon/CS241/Notes/compile.html - Jesper Juhl
3个回答

7

头文件由预处理器包含在编译单元 cpp 文件中。只有 cpp 文件中的源代码会在此之后被编译器编译。

如果您将函数定义放入头文件 .h 中,则不需要将此头文件包含在 main.cpp 中,因为预处理器不会将其包含在其中,编译器也不会对其进行编译。

您可以自行查看预处理器作业的结果。在 Visual Studio 中,使用 预处理器 属性页面上的 /P 选项。对于 main.cpp,输出将在 main.i 中。


3

头文件并不是单独编译的,可以将其想象为实际上在包含它的 .cpp 文件中。这个新的“合并”文件就是要被编译的文件。因此,您可以将函数放在头文件中,当它被包含在 .cpp 文件中时,它会被编译。

之所以不好的原因是,如果您在第二个 .cpp 文件中包含它,它将再次尝试进行编译,从而导致问题。


1
问题不在于头文件中的函数定义被跳过了,而是它们被编译了两次,这就太多了。C++有一个叫做“一次定义规则”的东西,如果一个函数被编译了两次,那么你就违反了这个规则。
需要提到一个重要的例外:inline函数是豁免的,并且可以在每个翻译单元中定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接