I'm trying to create a simple program that takes input from the user in C++ using good programming practices. It consists of Input.hpp, Input.cpp and main.cpp. I keep getting a multiple definition error even though I am using ifndef to prevent that.
我正在尝试创建一个简单的程序,该程序使用良好的编程实践在C++中接受用户的输入。它由Input.hpp、Input.cpp和main.cpp组成。即使我使用ifndef来防止出现多重定义错误,我也一直收到这种错误。
Input.hpp
Input.hpp
#ifndef Input_HPP
#define Input_HPP
#include <string>
#include <vector>
using namespace std;
vector<string> Get_Input();
vector<string> input_array;
string starting_position;
int input_number;
#endif
Input.cpp
Input.cpp
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include "Input.hpp"
using namespace std;
vector<string> Get_Input()
{
cin>>starting_position;
cin>>input_number;
for (int i = 0; i < input_number; i++)
{
cin>>input_array[i];
}
cout<<"Done";
return input_array;
}
main.cpp
Main.cpp
#include "Input.hpp"
#include <iostream>
using namespace std;
int main()
{
Get_Input();
return 0;
}
When I remove the variable declarations from the header file and put them in the cpp file but keep the function declaration in the header file the program builds without errors. It is my understanding that variables and functions can be declared in header files. Can someone please explain to me what I am missing?
当我从头文件中删除变量声明并将它们放入cpp文件中,但将函数声明保留在头文件中时,程序构建时没有错误。据我所知,变量和函数可以在头文件中声明。有人能给我解释一下我错过了什么吗?
Thank you.
谢谢。
更多回答
优秀答案推荐
The Header file isn't very smart, it just tells the pre-processor to take the whole header and put it instead of the include line.
头文件不是很智能,它只是告诉预处理器获取整个头文件并将其放入其中,而不是放入Include行。
if you do that, you can see the variable is declared twice.
如果这样做,您可以看到变量被声明了两次。
To solve the issue, you should declare the variables in one of your cpp files and use extern
in the headers.
要解决这个问题,您应该在一个CPP文件中声明变量,并在头文件中使用extern。
like in input.cpp:
如input.cpp中的:
int input_number;
and in input.hpp:
在input.hpp中:
extern int input_number;
The include guard only prevent copying the included file if it was already copied which is working correctly in your code and the compiler can compile the code successfully. Now what you getting is a linker error, after your compiler has generated the object files for Input.cpp
and main.cpp
it will find two symbols -variables- with the same name and will start to complain which one should I use?
Include保护仅在包含文件已复制且编译器可以成功编译代码的情况下才阻止复制包含文件,该包含文件在您的代码中工作正常。现在你得到的是一个链接器错误,在你的编译器为Input.cpp和main.cpp生成目标文件后,它会找到两个同名的符号-变量-并开始抱怨我应该使用哪一个?
So to sum up when you define a variable in a header file add the extern
keyword to keep the linker happy.
因此,总而言之,当您在头文件中定义变量时,添加EXTERN关键字以使链接器满意。
更多回答
I'm sorry but, which are the two symbols with the same name? If the include guard prevented copying input_number
in both files, wouldn't exist only one declaration of that variable?
对不起,请问这两个符号的名字是一样的?如果Include保护阻止复制两个文件中的INPUT_NUMBER,那么该变量不会只有一个声明吗?
@HansGD, Better late than never I suppose. The two .cpp files are compiled independently, potentially even by different code authors. The include guard stops you from including the same header multiple times in each. However, the preprocessor starts fresh for each, so the include guard won't help you across different .cpp files. Each one will end up with whatever symbols are defined in the header. The last step is linking the two resulting object files together, and it's then that the linker sees both definitions of each variable. Roughly, declarations don't own data, but definitions do.
@HansGD,我想迟到总比不到好。这两个.cpp文件是独立编译的,甚至可能由不同的代码作者进行编译。Include保护阻止您在每个文件中多次包含相同的标头。但是,每个文件的预处理器都是重新开始的,因此Include保护不会帮助您处理不同的.cpp文件。每一个都将以标题中定义的任何符号结尾。最后一步是将两个结果对象文件链接在一起,然后链接器才会看到每个变量的两个定义。粗略地说,声明并不拥有数据,但定义拥有。
我是一名优秀的程序员,十分优秀!