C ++:编译时获得多个“多重定义”错误

时间:2017-02-07 04:25:25

标签: c++ oop

我是类和面向对象编程的新手。我们的教师让我们创建一个必须包含.cpp文件,主.cpp文件和.hpp文件的程序。

以下是每个文件:

首先,odometer.hpp文件:

class Odometer
{
    int miles;
    float gallons, mpg;

public:
    //Constructors
    Odometer(); //Default
    Odometer(float g, int m); 

    //Mutator Functions
    void Set_miles(int m);
    void Set_gallons(float g);

    //Functions
    void Add_trip(int m, float g);
    int Check_mileage(float g);
    void Print_info();

    //Accessor Functions
    float Get_mpg();
    float Get_gallons();
    int Get_miles();
};

接下来是odometer.cpp文件:

#include "odometer.hpp"
#include <iostream>

//Constructors
Odometer::Odometer()
{
    miles = 0;
    gallons = 0.0;
    mpg = 0.0;
}

Odometer::Odometer(float g, int m)
{
    miles = m;
    gallons = g;
    mpg = m / g;
}

//Mutator functions
void Odometer::Set_miles(int m)
{
    miles = m;
}

void Odometer::Set_gallons(float g)
{
    gallons = float(g);
}

//Accessor functions
float Odometer::Get_mpg()
{
    return mpg;
}

float Odometer::Get_gallons()
{
    return gallons;
}

int Odometer::Get_miles()
{
    return miles;
}

//Other functions
//Takes # of gallons & # of miles and adds it to previous values, calculating
//new miles/gallon for whole trip
void Odometer::Add_trip(int m, float g)
{
    miles += m;
    gallons += g;
    mpg = miles / gallons;
}

int Odometer::Check_mileage(float g)
{
    int newMiles = g * mpg;
    return newMiles;
}

void Odometer::Print_info()
{
    std::cout << "Miles:   " << miles << "     Gallons: " << gallons << 
"     Miles/Gallon: " << mpg;
}

最后,odometer_main.cpp文件(到目前为止,它还不完整):

#include <iostream>
#include "odometer.cpp"

using namespace std;

int main(void)
{
    //Odometer odDefault; //Odometer object set to defaults
    Odometer od(10, 100); //Odometer object with values set
    return 0;
}

这些是我在尝试编译所有文件时遇到的错误:

/tmp/ccArjYHP.o: In function 'Odometer::Odometer()':
odometer_main.cpp:(.text+0x0): multiple definition of 'Odometer::Odometer()'  
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x0): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Odometer()':
odometer_main.cpp:(.text+0x0): multiple definition of 'Odometer::Odometer()'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x0): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Odometer(float, int)':
odometer_main.cpp:(.text+0x30): multiple definition of 'Odometer::Odometer(float, int)'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x30): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Odometer(float, int)':
odometer_main.cpp:(.text+0x30): multiple definition of 'Odometer::Odometer(float, int)'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x30): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Set_miles(int)':
odometer_main.cpp:(.text+0x72): multiple definition of 'Odometer::Set_miles(int)'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x72): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Set_gallons(float)':
odometer_main.cpp:(.text+0x8a): multiple definition of 'Odometer::Set_gallons(float)'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x8a): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Get_mpg()':
odometer_main.cpp:(.text+0xa8): multiple definition of 'Odometer::Get_mpg()'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0xa8): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Get_gallons()':
odometer_main.cpp:(.text+0xbc): multiple definition of 'Odometer::Get_gallons()'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0xbc): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Get_miles()':
odometer_main.cpp:(.text+0xd0): multiple definition of 'Odometer::Get_miles()'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0xd0): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Add_trip(int, float)':
odometer_main.cpp:(.text+0xe0): multiple definition of 'Odometer::Add_trip(int, float)'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0xe0): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Check_mileage(float)':
odometer_main.cpp:(.text+0x140): multiple definition of 'Odometer::Check_mileage(float)'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x140): first defined here
/tmp/ccArjYHP.o: In function 'Odometer::Print_info()':
odometer_main.cpp:(.text+0x168): multiple definition of 'Odometer::Print_info()'
/tmp/cc1W9Ght.o:odometer.cpp:(.text+0x168): first defined here
collect2: error: ld returned 1 exit status
makefile:2: recipe for target 'odometer' failed
make: *** [odometer] Error 1

4 个答案:

答案 0 :(得分:1)

简而言之,将#include "odometer.cpp"替换为#include "odometer.hpp"。现在为什么。

您的计划包含main.cppodometer.cpp等源文件。这些文件包含项目中函数,变量或类的定义。您的编译器将每个源文件(.cpp)分别编译为目标文件(.o),然后您的链接器将这些目标文件链接在一起以形成您的程序。

但是,虽然您的源文件是单独编译的,但它们需要相互交互。 main.cpp将要创建Odometer个对象并访问Odometer个成员函数,依此类推。因此,我们需要一种方法来告诉main.cpp Odometer是什么。最简单的方法是在头文件中定义Odometer,在#include中定义main.cpp标题。

#include是一个预处理程序指令,它将另一个文件的内容插入到当前文件中。预处理器在实际编译代码之前运行。我们的想法是,您在文件中有一些声明,我们称之为头文件,以及需要访问这些声明的多个源文件。因此,每个源文件都会#include标题。

请注意main.cpp不需要访问Odometer成员函数的定义,只需知道这些函数是什么是以及如何称呼他们。该信息位于odometer.hpp中的类定义中,而不是odometer.cpp中。这对#include "odometer.cpp"来说是错误的,因为那时我们会有两个不同位置定义的函数,链接器会抱怨。

因此,通常将类定义放在头文件(.hpp)中,将类实现放在源文件(.cpp)中,并将#include头文件放在任何文件中需要访问该类的其他源文件。如果您以这种方式正确构建程序,则永远不需要将#include .cpp个文件存入另一个.cpp文件。

答案 1 :(得分:0)

如果要将odometer.cpp包含在odometer_main.cpp中,则不能单独编译odometer.cpp并将其与odometer_main.cpp链接。在那种情况下,是的,你会得到重复的符号。但是,典型的方法是只将.hpp文件包含在main中,其他所有文件都应该编译和链接。

答案 2 :(得分:0)

这里有多个问题:

<强> odometer.hpp

  • Odometer(float g, int m)odometer.cpp
  • 中未对此进行定义
  • Odometer():此默认构造函数也应在odometer.cpp

  • 中定义
  • 里程表有三个成员变量但只有两个作为输入,目前还不清楚第三个mpg是如何初始化的

  • 您的标头文件中没有包含警戒

    #ifdef ODO_H

    #define ODO_H

    class Odometer{  // your class declaration };

    #endif

<强> odometer.cpp

  • #include "odometer.hpp"

  • #include <iostream> - 因为您使用的是std::cout

  • 提供各种Odometer构造函数的定义。

<强>的main.cpp

  • #include "odometer.hpp" - 因为你在这里使用里程表课程

解决这些问题应该可以帮助您编译代码。

答案 3 :(得分:0)

使用文件排除指令非常重要,以避免多次包含。

#ifndef ODOMETER_H
#define ODOMETER_H
#include "odometer.h"
#endif

看看这个问题:

Why are #ifndef and #define used in c++ header files

另外,正如大家评论的那样,你应该包含h文件