C++ 包括 .cpp 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19547091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:56:58  来源:igfitidea点击:

Including .cpp files

c++

提问by

I have read in places like herethat you have to include .h files and not .cpp files, because otherwise then you get an error. So for example

我在像这里这样的地方读到你必须包含 .h 文件而不是 .cpp 文件,否则你会得到一个错误。所以例如

main.cpp

主程序

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

int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}

foop.h

foop.h

#ifndef FOOP_H
#define FOOP_H
int foo(int a);
#endif

foop.cpp

foop.cpp

int foo(int a){
    return ++a;
}

works, but if I replace #include "foop.h"with #include "foop.cpp"I get an error (Using Dev C++ 4.9.9.2, Windows):

有效,但如果我替换#include "foop.h"#include "foop.cpp"我得到一个错误(使用 Dev C++ 4.9.9.2,Windows):

multiple definition of foo(int)
first defined here

Why is this?

为什么是这样?

采纳答案by xorguy

What includedoes is copying all the contents from the file (which is the argument inside the <>or the ""), so when the preproccesor finishes its work main.cppwill look like:

什么include是从文件中复制所有内容(这是<>或 中的参数""),因此当预处理器完成其工作时main.cpp将如下所示:

// iostream stuff

int foo(int a){
    return ++a;
}

int main(int argc, char *argv[])
{
   int x=42;
   std::cout << x <<std::endl;
   std::cout << foo(x) << std::endl;
   return 0;
}

So foo will be defined in main.cpp, but a definition also exists in foop.cpp, so the compiler "gets confused" because of the function duplication.

因此 foo 将在 中定义main.cpp,但在 中也存在定义foop.cpp,因此编译器会因为函数重复而“感到困惑”。

回答by Mark Ransom

There are many reasons to discourage including a .cpp file, but it isn't strictly disallowed. Your example should compile fine.

有很多理由不鼓励包含 .cpp 文件,但并非严格禁止。您的示例应该可以正常编译。

The problem is probably that you're compiling both main.cpp and foop.cpp, which means two copies of foop.cpp are being linked together. The linker is complaining about the duplication.

问题可能是您正在编译 main.cpp 和 foop.cpp,这意味着 foop.cpp 的两个副本被链接在一起。链接器抱怨重复。

回答by rob mayoff

When you say #include "foop.cpp", it is as if you had copied the entire contents of foop.cppand pasted it into main.cpp.

当你说的时候#include "foop.cpp",就好像你已经复制了整个内容foop.cpp并粘贴到了main.cpp

So when you compile main.cpp, the compiler emits a main.objthat contains the executable code for two functions: mainand foo.

因此,当您 compile 时main.cpp,编译器会发出main.obj包含两个函数的可执行代码的a :mainfoo

When you compile foop.cppitself, the compiler emits a foop.objthat contains the executable code for function foo.

当你自己编译时foop.cpp,编译器会发出一个foop.obj包含函数的可执行代码foo

When you link them together, the compiler sees two definitions for function foo(one from main.objand the other from foop.obj) and complains that you have multiple definitions.

当您将它们链接在一起时,编译器会看到两个函数定义foo(一个来自main.obj,另一个来自foop.obj)并抱怨您有多个定义。

回答by dasblinkenlight

This boils down to a difference between definitionsand declarations.

这归结为定义声明之间的区别。

  • You can declare functions and variables multiple times, in different translation units, or in the same translation unit. Once you declare a function or a variable, you can use it from that point on.
  • You can define a non-static function or a variable only once in all of your translation units. Defining non-static items more than once causes linker errors.
  • 您可以在不同的翻译单元或同一翻译单元中多次声明函数和变量。一旦你声明了一个函数或一个变量,你就可以从那时起使用它。
  • 您只能在所有翻译单元中定义一次非静态函数或变量。多次定义非静态项会导致链接器错误。

Headers generally contain declarations; cpp files contain definitions. When you include a file with definitions more than once, you get duplicates during linking.

标头通常包含声明;cpp 文件包含定义。当您多次包含具有定义的文件时,您会在链接期间得到重复项。

In your situation one defintion comes from foo.cpp, and the other definition comes from main.cpp, which includes foo.cpp.

在您的情况下,一个定义来自foo.cpp,另一个定义来自main.cpp,其中包括foo.cpp.

Note:if you change footo be static, you would have no linking errors. Despite the lack of errors, this is nota good thing to do.

注意:如果更改foostatic,则不会出现链接错误。尽管没有错误,但这不是一件好事。

回答by benjymous

Because your program now contains two copies of the foofunction, once inside foo.cpp and once inside main.cpp

因为您的程序现在包含该foo函数的两个副本,一次在 foo.cpp 中,一次在 main.cpp 中

Think of #include as an instruction to the compiler to copy/paste the contents of that file into your code, so you'll end up with a processed main.cpp that looks like this

将#include 视为编译器的指令,以将该文件的内容复制/粘贴到您的代码中,因此您最终会得到一个处理过的 main.cpp,如下所示

#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it!
int foo(int a){
    return ++a;
}

int main(int argc, char *argv[])
{
int x=42;
std::cout << x <<std::endl;
std::cout << foo(x) << std::endl;
return 0;
}

and foo.cpp

和 foo.cpp

int foo(int a){
    return ++a;
}

hence the multiple definition error

因此多重​​定义错误

回答by John Dibling

Because of the One Definition Rule(probably1).

因为一个定义规则(可能是1)。

In C++, each non-inline object and function must have exactly onedefinition within the program. By #includeing the file in which foo(int)is defined (the CPP file), it is defined both in every file where foop.cpp is #included, and in foop.cpp itself (assuming foop.cpp is compiled).

在 C++ 中,每个非内联对象和函数在程序中必须只有一个定义。通过#includeing 在其中foo(int)定义的文件(CPP 文件),它在 foop.cpp 为#included 的每个文件中以及 foop.cpp 本身中都被定义(假设 foop.cpp 已编译)。

You can make a function inlineto override this behavior, but I'm not recommending that here. I have never seen a situation where it is necessary or even desirable to #includea CPP file.

您可以创建一个函数inline来覆盖此行为,但我不建议在这里这样做。我从未见过需要或什至#include需要 CPP 文件的情况。

There are situations where it is desireable to include a definition of something. This is specially true when you try to seperate the definition of a template from the declaration of it. In those cases, I name the file HPP rather than CPP to denote the difference.

在某些情况下,希望包含某物的定义。当您尝试将模板的定义与其声明分开时,尤其如此。在这些情况下,我将文件命名为 HPP 而不是 CPP 来表示差异。



1: "(probably)" I say probably here because the actual code you've posted should compile without errors, but given the compiler error it seems likely that the code you posted isn't exactlythe same as the code you're compiling.

1:“(可能)”我在这里说可能是因为您发布的实际代码应该可以编译而不会出错,但是考虑到编译器错误,您发布的代码似乎与您正在编译的代码不完全相同.

回答by Junho Cha

You should just include header file(s).

您应该只包含头文件。

If you include header file, header file automatically finds .cpp file. --> This process is done by LINKER.

如果包含头文件,头文件会自动查找 .cpp 文件。--> 这个过程是由LINKER完成的。

回答by Daedric

So I found that if you are compiling from Visual Studios you just have to exclude the included .cpp file from the final build (that which you are extending from):

所以我发现如果你是从 Visual Studios 编译你只需要从最终版本中排除包含的 .cpp 文件(你正在扩展的那个):

Visual Studios: .cpp file > right click > properties > configuration properties > general > excluded from build > yes

Visual Studios:.cpp 文件 > 右键单击​​ > 属性 > 配置属性 > 常规 > 从构建中排除 >

I believe you can also exclude the file when compiling from the command line.

我相信您也可以在从命令行编译时排除该文件。

回答by user3409438

Using ".h" method is better But if you really want to include the .cpp file then make foo(int) static in foo.cpp

使用“.h”方法更好但是如果你真的想包含 .cpp 文件,那么在 foo.cpp 中将 foo(int) 设为静态