C++中的多个定义错误以及解决此问题的解决方案

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18914122/
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:20:17  来源:igfitidea点击:

multiple definitions error in c++ and solution to solve this issue

c++compiler-errorslinkagemultiple-definition-error

提问by starkk92

I am new to C++. I have some doubts regarding multiple definitions error in C++.

我是 C++ 的新手。我对 C++ 中的多重定义错误有一些疑问。

Let's say I have 3 files in a program. One header file and 2 .cpp files. I have included the header file in both the .cpp files.

假设我在一个程序中有 3 个文件。1 个头文件和 2 个 .cpp 文件。我在两个 .cpp 文件中都包含了头文件。

  1. I have declared a class in the header file and I have defined the class in each of the .cpp files in exactly the same way. So will this type of implementation cause multiple definitions error? If so, is it because it has two copies of class definitions and the compiler doesn't know which one to take during linkage of two .o files?
  1. 我在头文件中声明了一个类,并以完全相同的方式在每个 .cpp 文件中定义了该类。那么这种类型的实现会导致多重定义错误吗?如果是这样,是不是因为它有两个类定义副本,而编译器不知道在链接两个 .o 文件期间应该采用哪一个?

Can we solve this problem by using externin header file and defining the class in only one of the files?If we can solve the issue by using this method,do we have to include the .cpp(with class definition) into other .cpp file(with no class definition)?

可以通过extern在头文件中使用,只在其中一个文件中定义类来解决吗(没有类定义)?

  1. I have declared and defined a class in header file. Is this case the same as above (mentioned in 1)?

  2. I have declared a class in the header file and I have defined the class in each of the .cpp files but the definitions (function bodies)differs. So will this type of implementation causes multiple definitions error? If so, how can we solve this problem where the functions bodies differs in the .cpp files?

  1. 我已经在头文件中声明并定义了一个类。这种情况是否与上述相同(在 1 中提到)?

  2. 我已经在头文件中声明了一个类,并且我已经在每个 .cpp 文件中定义了这个类,但是定义(函数体)不同。那么这种类型的实现会导致多重定义错误吗?如果是这样,我们如何解决 .cpp 文件中函数体不同的问题?

回答by john

1) You solve this by 'defining the class' in only one cpp file. Why would you want to define it in two files?

1) 您可以通过仅在一个 cpp 文件中“定义类”来解决此问题。为什么要在两个文件中定义它?

2) Don't define things in header files, only declare them. There are exceptions to this rule, for instance inline functions. Also classes themselves can defined more than once (by this I mean declaring the methods and data members of the class, (i.e. writing class XYZ { ... };) but each definition must be identical. The simplest way to achieve this is to define a class once in a header file. Then each definition resulting from including that header file in multiple places will necessarily be identical.

2)不要在头文件中定义东西,只声明它们。这条规则也有例外,例如内联函数。类本身也可以定义多次(我的意思是声明类的方法和数据成员,(即编写class XYZ { ... };)但每个定义必须相同。实现这一点的最简单方法是在头文件中定义一次类. 那么在多个位置包含该头文件所产生的每个定义都必然是相同的。

3) This one is even sillier, it's one thing to define somethiing twice, but define it twice and differently each time makes even less sense.

3)这个更愚蠢,定义两次是一回事,但定义两次并且每次都不同更没有意义。

I guess the issue is why you think it might sometimes be necessary to define things more than once. Don't do that.

我想问题是为什么您认为有时可能需要多次定义事物。不要那样做。

You should also make it clear what you mean by 'define the class'. I've taken that to mean define the methods and static members of the class. But if you have something else in mind that might be a source of confusion. As usual the best way to avoid this kind of terminology confusion is to post some code.

您还应该明确“定义类”的含义。我认为这意味着定义类的方法和静态成员。但是,如果您有其他想法,这可能会造成混乱。像往常一样,避免这种术语混淆的最佳方法是发布一些代码。

回答by Agentlien

To answer all of these questions, you only need to look at the purpose of declarations and definitions.

要回答所有这些问题,您只需查看声明和定义的目的。

Declarations of a class simply state that the class exists and in which context. For a class, a simple forward declaration (e.g. class Banana;) allows you to use pointers or references to that class, but that's it.

类的声明只是声明该类存在以及在哪个上下文中。对于一个类,一个简单的前向声明(例如class Banana;)允许您使用该类的指针或引用,但仅此而已。

Definitions state exactly what the class is. That is, which members it has and from what base classes it is derived. You need this available whenever you access members of the class, or need to know the size of its instances. This means the class definition needs to be put in a header file, so that it can be included wherever in all files which use the class. This is OK, because the standard says that a class can be defined in multiple translation units, as long as all definitions are identical.

定义准确地说明了类是什么。也就是说,它具有哪些成员以及它从哪些基类派生。每当您访问类的成员或需要知道其实例的大小时,您都需要它。这意味着类定义需要放在头文件中,以便它可以包含在所有使用该类的文件中的任何位置。这是可以的,因为标准说一个类可以在多个翻译单元中定义,只要所有定义都相同。

A class definition typically looks something like this:

类定义通常如下所示:

class Banana
{
public: 
  Banana(){}

  void eat();

private:
  //....
};

However, please note that this class definition only means the definition of the class itself, not the non-inline member functions. Such as void eat()in the above example. These need to be defined in the .cpp file, because they may not be defined in multiple translation units.

但是请注意,这个类定义仅指类本身的定义,而不是非内联成员函数。比如void eat()上面的例子。这些需要在 .cpp 文件中定义,因为它们可能不会在多个翻译单元中定义。

So in short:

简而言之:

  1. This is not right, only define it in the header file and define non-inline member functions in the matching .cpp file. You should never define the same function or type in more than one file.
  2. This is OK, as long as you define the member functions separately in the .cpp file.
  3. No, see 1.
  1. 这是不对的,只能在头文件中定义,并在匹配的.cpp文件中定义非内联成员函数。永远不要在多个文件中定义相同的函数或类型。
  2. 这没问题,只要您在 .cpp 文件中单独定义成员函数即可。
  3. 不,见 1。

回答by Pete Becker

There's no problem with defining a class in several places. That's exactly what happens when you put the definition in a header and #includethat header in more than one source file. However, note that defining a class means writing out what the class contains, not defining its members. This is a class definition:

在几个地方定义一个类没有问题。这正是当您将定义放在一个头文件中并将#include该头文件放在多个源文件中时会发生的情况。但是,请注意,定义类意味着写出类包含的内容,而不是定义其成员。这是一个类定义:

class C {
    void f();     // member function declaration
    void g() { }  // member function declaration with inline definition
    int i;        // member declaration
    static int j; // member declaration
};

like most things, you can't define it more than once in a single source file. However, it can appear in as many source files as you like, provided only that it's the same everywhere.

像大多数事情一样,您不能在单个源文件中多次定义它。但是,它可以出现在任意数量的源文件中,前提是它在任何地方都相同。

This class definition declares two members that must be defined somewhere, typically like this:

此类定义声明了两个必须在某处定义的成员,通常如下所示:

void C::f() {
    std::cout << "In C::f\n";
}

int C::j = 3;

These definitions can appear only once in the entire program; usually each is defined once in a source file.

这些定义在整个程序中只能出现一次;通常每个都在源文件中定义一次。

回答by Vadim Prozorov

1) You can't have two definitions of the same class in your project. And I have no idea how you plan to use it. If you want to make instances of one class with different behavior, use virtual function like:

1) 项目中不能有同一个类的两个定义。我不知道你打算如何使用它。如果要使一个类的实例具有不同的行为,请使用虚拟函数,例如:

class A {
public:
    virtual int foo() = 0;
}

class B : public A {
public:
    virtual int foo() { return 1; }
}

class C : public A {
public:
    virtual int foo() { return 2; }
}

2) You may define class in header file (java-style), but it's not the best idea because compiler will consume more resources to build other files, include this header. Let compiler work fast - define classes in .cpp files.

2)你可以在头文件(java风格)中定义类,但这不是最好的主意,因为编译器会消耗更多的资源来构建其他文件,包括这个头文件。让编译器快速工作 - 在 .cpp 文件中定义类。

3) See p.1

3) 见第 1 页