Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.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++; 我的'Health.h文件包括基本C++标题< /p> #include <iostream> #include <cstring> // and many header files._C++_Header Files_Multiple Definition Error - Fatal编程技术网

多定义错误c++; 我的'Health.h文件包括基本C++标题< /p> #include <iostream> #include <cstring> // and many header files.

多定义错误c++; 我的'Health.h文件包括基本C++标题< /p> #include <iostream> #include <cstring> // and many header files.,c++,header-files,multiple-definition-error,C++,Header Files,Multiple Definition Error,为类A编写代码 A.h级 classA.cpp // Contains #include "Headers.h" #include "common_utility.h" #include "classA.h" // class A Method definition 为类B编写代码 我在B班使用A班 B.h类 class B { // Contains class A Declarations. } 类别b.cpp // Contains #include "Headers.h"

为类A编写代码 A.h级

classA.cpp

// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"

// class A Method definition
为类B编写代码 我在B班使用A班

B.h类

 class B
    {
// Contains class A Declarations.
}
类别b.cpp

// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
#include "classB.h"

// class B Method definition
// calling the function ifFileExist() in class B also.
为主程序编写代码 main.cpp

当我把整个程序编译成

g++-std=c++0x classA.cpp classB.cpp main.cpp-o main

我得到以下错误

在函数
ifFileExist()中:classB.cpp:(.text+0x0):多个
定义
ifFileExist() /tmp/ccHkDT11.o:classA.cpp:(.text+0x2b6e):首先在这里定义

因此,我将Headers.h中的ifFileExist()函数作为extern进行了清除

extern bool ifFileExist();
但我还是犯了同样的错误

我在每个.cpp文件中都包含“Headers.h”。该文件包含基本的C++库。但是我没有得到任何头文件的多定义错误。 但仅在我自己的函数中,我得到了错误“多重定义”

我想在需要时使用“common_utility.h”文件。如果我不需要在我的主程序中使用公共_实用程序函数,我就不应该包括它

我希望我的程序在以下每种情况下运行

g++-std=c++0x classA.cpp main.cpp-o main
g++-std=c++0x classB.cpp>main.cpp-o main
g++-std=c++0x classA.cpp classB.cpp main.cpp-o main


我不应该在任何情况下得到多个定义错误。我现在该怎么办

在实际编译源代码之前,编译单元是从.cpp文件生成的。这基本上意味着计算所有预处理器指令:所有
#include
将替换为包含文件的内容,所有
#define
'd值将替换为相应的表达式,所有
#如果0#将移除EndoF等。因此,在您的案例中,在没有任何预处理器指令的情况下,您将得到两块C++代码,这些指令都具有相同函数的定义:代码> BoOL IfIFILIVE()/CODE >,这就是为什么您得到这个多重定义错误。

快速解决方案是将其标记为
inline bool ifFileExist()
。基本上,您要求编译器用函数本身的内容替换所有相应的函数调用


另一种方法是在
common\u utility.h
中声明函数,并将定义移动到
common\u utility.cpp

,因为在我看来,这个问题找不到任何完整的重复项,所以我将写一个(希望是)权威的完整答案

一个定义规则是什么?我为什么要在意 单定义规则(通常称为ODR)是一种规则,它规定(简化)程序中使用的任何实体(非正式术语)都应该定义一次,而且只能定义一次。多次定义的实体通常会导致编译或链接器错误,但有时编译器无法检测到该实体,并导致很难跟踪错误

我不打算在这里正式定义实体,但可以将其视为函数、变量或类。在深入研究之前,我们应该清楚地理解C++中的<强>定义<强>和<强>声明>强,因为禁止双重定义时,通常会避免双重声明。 定义与声明 代码中使用的每个实体都应该在给定的翻译单元中声明(翻译单元通常是cpp源文件以及包含在其中的所有头文件,直接或间接通过其他头文件)。实体的声明方式因实体本身而异。有关如何声明不同类型的实体,请参见下文。实体通常在头文件中声明。由于大多数复杂的应用程序中有多个翻译单元(多个cpp文件),并且不同的cpp文件通常包含相同的头,因此一个应用程序可能会对使用的许多实体进行多个声明。就像我上面说的,这不是问题

应用程序中使用的每个实体必须定义一次且仅定义一次。术语“应用程序”在这里使用得有点松散-例如,库(静态和动态)中可以有未定义的实体(此时通常称为符号),链接到使用动态库的可执行文件也可以有未定义的符号。相反,我指的是,在所有库都静态或动态链接到应用程序中并解析符号之后,应用程序是最终运行的

还值得注意的是,每一个定义都是一个声明,也就是说,每当你定义某件事时,你也在声明同一件事

与声明一样,定义实体的方式因实体的类型而异。下面是如何根据实体的类型声明/定义3种基本类型的实体——变量、类和函数

变量 使用以下构造声明变量:

extern int x;
class X;
class X {
   public:
   int y;
};
这声明了一个变量x。它没有定义它!以下代码将被编译为OK,但如果尝试在没有任何其他输入文件的情况下链接它(例如,使用
g++main.cpp
),将由于未定义的符号而产生链接时间错误:

extern int x;
int main() {
    return x;
}
以下代码定义变量x:

int x;
如果将这一行放在文件x.cpp中,并使用
g++x.cpp main.cpp-o test
从上面将该文件与main.cpp编译/链接在一起,则编译和链接将不会出现问题。您甚至可以运行生成的可执行文件,如果要在可执行文件运行后检查退出代码,您会注意到它是0。(因为全局变量x默认初始化为0)

功能 函数是通过提供它们的原型来声明的。典型的函数声明如下所示:

double foo(int x, double y);
(in x.h)
extern int x; //declare x

(in x.xpp)
int x; // define x

// 1.cpp and 2.cpp remain the same
(in x.h)
int x_func() { return 42; }
(in a.h)
#ifndef INCLUDED_A_H
#define INCLUDED_A_H

class A { };

#endif
这个构造声明了一个函数
foo
,返回
double
a
inline void foo() { }
inline void foo() { }
class A {
public:
    int foo() { return 42; }
};
class X;
X* p; // OK - no information about class X is actually required to define a pointer to it
p->y = 42; // Error - compiler has no idea if X has any member named `y`

void foo(X x); // OK - compiler does not need to generated any code for this

void foo(X x) { } // Error - compiler needs to know the size of X to generate code for foo to properly read it's argument
void bar(X* x) { } // OK - compiler needs not to know specifics of X for this
class X {
   public:
   int y;
};
int x;
int x; // ODR violation

void foo() {
   int x;
} // No ODR violation, foo::x is different from x in the global scope
(in x.h)
int x;

(in 1.cpp)
#include <x.h>
void set_x(int y) {
   x = y;
}

(in 2.cpp)
#include <x.h>
int get_x() {
    return x;
}
(in x.h)
extern int x; //declare x

(in x.xpp)
int x; // define x

// 1.cpp and 2.cpp remain the same
(in x.h)
int x_func() { return 42; }
(in x.h)
int x_func();

(in x.cpp)
int x_func() { return 42; } 
(in a.h)
class A { };

(in main.cpp)
#include <a.h>
#include <a.h> // compilation error!
(in foo.h)
#include <a.h>

(in main.cpp)
#include <a.h>
#include <foo.h>
(in a.h)
#ifndef INCLUDED_A_H
#define INCLUDED_A_H

class A { };

#endif