Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多声明vs未定义_C++_C++11 - Fatal编程技术网

C++ 多声明vs未定义

C++ 多声明vs未定义,c++,c++11,C++,C++11,我试图从一个文件中导入变量,该文件在另一个文件中的类中使用,并最终将其导入另一个文件并编译 让我来说明问题的重现情况: arrayFile.hpp int arr[] = { 1,2,6,5,4,3 }; classFile.hpp #include <iostream> using namespace std; #include "arrayFile.hpp" class MyClass{ private: int v1; public: MyCl

我试图从一个文件中导入变量,该文件在另一个文件中的类中使用,并最终将其导入另一个文件并编译

让我来说明问题的重现情况:

arrayFile.hpp

int arr[] = {
  1,2,6,5,4,3
};
classFile.hpp

#include <iostream>

using namespace std;

#include "arrayFile.hpp"

class MyClass{
private:
    int v1;  

public:
    MyClass();
    void setV(int v);
    int getV();
    int funcM();
};
如果我这样做:

In file included from mainfile.cpp:5:0:
classFolder/arrayFile.hpp:1:9: error: redefinition of ‘int arr []’
 int arr[] = {
         ^
In file included from classFolder/classFile.hpp:3:0,
                 from mainfile.cpp:4:
classFolder/arrayFile.hpp:1:5: note: ‘int arr [6]’ previously defined here
 int arr[] = {
     ^
我已经能够让编译器告诉我arr[]也没有定义,但是我无法重现这个错误

我做错了什么


我面临的真正问题需要我将数组和结构导入到一个类中,这个类被导入到另一个更大的类中,最后一个类最终被main使用。这是我复制它的最好方法。我不知道如何解决这个问题。

您不应该在classFile.hpp中包含arrayFile.hpp。仅将其包含在classFile.cpp中。另外,在mainfile.cpp中,在主函数之前添加行

extern int arr[];
这一行告诉编译器称为arr的int类型数组将在与mainfile.cpp链接在一起的其他cpp文件中定义

按如下方式编译程序:

g++ -std=c++11 -c main.cpp classFile.cpp
g++ -std=c++11 main.o classFile.o
./a.out
第一行分别编译文件,创建main.o和classFile.o文件 第二行将它们链接在一起,创建一个可执行文件a.out 第三行运行可执行文件


由于添加新文件使编译过程变得复杂,我建议使用Makefile。

您不应该在classFile.hpp中包含arrayFile.hpp。仅将其包含在classFile.cpp中。另外,在mainfile.cpp中,在主函数之前添加行

extern int arr[];
这一行告诉编译器称为arr的int类型数组将在与mainfile.cpp链接在一起的其他cpp文件中定义

按如下方式编译程序:

g++ -std=c++11 -c main.cpp classFile.cpp
g++ -std=c++11 main.o classFile.o
./a.out
第一行分别编译文件,创建main.o和classFile.o文件 第二行将它们链接在一起,创建一个可执行文件a.out 第三行运行可执行文件


由于添加新文件使编译过程变得复杂,我建议使用Makefile。

广义上讲,在头文件中定义变量不是一个好主意-假设所述头文件将由多个源文件包含

编译项目时,预处理器通过将包含的头文件的内容放入包含它的文件中来处理include语句。 例如:

这是一种简化,但足以说明问题。 那么在你的例子中发生了什么? arrayFile.hpp包含在classFile.hpp中,classFile.hpp包含在classFile.cpp和mainfile.cpp中。考虑包含树:

可能是有帮助的。
           arrayFile.hpp
                |
           classFile.hpp
             /       \
   classFile.cpp    mainfile.cpp
想一想我说的:用包含的文件内容替换包含,看看我说classFile.cpp和mainfile.cpp都以arr数组的定义结束时,您是否不同意

在编译项目时,接下来会发生什么?编译器将源代码(特别是预处理器输出)编译为对象文件。例如,预处理的classFile.cpp变成classFile.o,预处理的mainfile.cpp变成mainfile.o

最后,将对象文件或它们归档到的库链接起来,形成可执行文件

当链接器尝试链接classFile.o和mainfile.o时,它会发现两者都定义了arr。因此,您得到的是多定义链接器错误,而不是编译器错误

因此:如果一个头文件被多个源文件直接或间接包含,那么如果头文件定义了变量,您将遇到链接器错误。这就是为什么,在头文件中声明变量并在一个源文件中定义它们是标准做法


希望这会有所帮助。

一般来说,在头文件中定义变量不是一个好主意-假设所述头文件将包含在多个源文件中

编译项目时,预处理器通过将包含的头文件的内容放入包含它的文件中来处理include语句。 例如:

这是一种简化,但足以说明问题。 那么在你的例子中发生了什么? arrayFile.hpp包含在classFile.hpp中,classFile.hpp包含在classFile.cpp和mainfile.cpp中。考虑包含树:

可能是有帮助的。
           arrayFile.hpp
                |
           classFile.hpp
             /       \
   classFile.cpp    mainfile.cpp
想一想我说的:用包含的文件内容替换包含,看看我说classFile.cpp和mainfile.cpp都以arr数组的定义结束时,您是否不同意

在编译项目时,接下来会发生什么?编译器将源代码(特别是预处理器输出)编译为对象文件。例如,预处理的classFile.cpp变成classFile.o,预处理的mainfile.cpp变成mainfile.o

最后,将对象文件或它们归档到的库链接起来,形成可执行文件

当链接器尝试链接classFile.o和mainfile.o时,它会发现两者都定义了arr。这样就得到了多定义链接器 错误-不是编译器错误

因此:如果一个头文件被多个源文件直接或间接包含,那么如果头文件定义了变量,您将遇到链接器错误。这就是为什么,在头文件中声明变量并在一个源文件中定义它们是标准做法


希望这能有所帮助。

始终标记主语言,并改进以下问题:我应该如何在终端中使用g++-std=c++11编译所有语言?只需列出所有.cpp文件,您就可以得到问题的答案。但是,如果你不这样做,那么考虑编写A来说明你的主要观点。ARR不应该在页眉中定义。我怀疑是否应该避免使用全局变量。我假设您不允许使用std::array或std::vector?虽然您确实标记了c++11,但也始终标记了主语言,在这个问题上有所改进,我应该如何在终端中使用g++-std=c++11来编译它呢?只需列出所有.cpp文件,您就可以得到问题的答案。但是,如果你不这样做,那么考虑编写A来说明你的主要观点。ARR不应该在页眉中定义。我怀疑是否应该避免使用全局变量。我假设您不允许使用std::array或std::vector?虽然您标记了c++11
// main.cpp
#include "foo.h"
int main( int argc, char* argv[] )
{
  return 0;
}
// preprocessor output

typedef int myInt;

int main( int argc, char* argv[] )
{
  return 0;
}
           arrayFile.hpp
                |
           classFile.hpp
             /       \
   classFile.cpp    mainfile.cpp