头文件是否未编译(C ++ Visual Studio 2015)

时间:2016-11-23 22:25:05

标签: c++ visual-studio-2015

只是为了看它是否可行(我知道它的形式很糟糕),我在头文件中完全定义了一个函数,并在主cpp文件中为所述函数做了相应的前向声明。 C ++函数不需要在它们使用的转换单元中定义,因此为什么头文件几乎完全只是前向声明(内联函数除外)。但是,当我试图编译这个项目时,它说有一些未解决的外部因素。

当我将头文件的全部内容移动到源文件中时(也删除头文件),它编译得很好并按预期执行。那么,在构建项目时是不是编译了头文件,还是只有一些我不了解的例外?

此外,即使我只是转到属性资源管理器中的头文件属性并将其File Type设置为C/C++ Code并将其扩展名更改为.cpp,它仍然会赢得&#39 ; t编译(即使它会删除它并创建一个新的源文件,我认为这是最奇怪的部分)。

(我正在使用已停用的扩展程序/Za,如果这会改变任何内容)

这是代码文件

//main.cpp
void foo();

void main()
{
    foo();
}

和头文件

//test.h
#include <iostream>

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

3 个答案:

答案 0 :(得分:4)

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

将函数定义放入标题.h文件中时。您不将此头文件包含到main.cpp中,并且编译器不会编译它,因为预处理器不会将其包含在main.cpp中。

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

答案 1 :(得分:1)

头文件不是自己编译的,只是想象一下文本实际上在包含它的.cpp文件中。这个新的'merged'文件是编译的。因此,您可以将函数放在头文件中,并在将其包含在.cpp文件中时进行编译。

它不好的原因是,如果你将它包含在第二个.cpp文件中,它将尝试再次编译,你将遇到问题。

答案 2 :(得分:1)

标题中函数定义的问题并不是它们被跳过。真正的风险是他们被编译了两次,这曾经太多了。 C ++有一个称为单一定义规则的东西,你通过两次编译单个函数来违反该规则。

有一个重要的例外:inline函数可以免除,并且可以在每个翻译单元中定义。