簡體   English   中英

C ++:編譯時出現多個“多個錯誤的定義”錯誤

[英]C++: Getting multiple “multiple definition of” errors when compiling

我是類和面向對象編程的新手。 我們的老師正在讓我們創建一個程序,該程序必須具有.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

簡而言之,將#include "odometer.cpp"替換為#include "odometer.hpp" 現在,為什么。

您的程序由main.cppodometer.cpp類的源文件組成。 這些文件包含項目中函數,變量或類的定義。 編譯器將每個源文件( .cpp )分別編譯為目標文件( .o ),然后鏈接程序將這些目標文件鏈接在一起以形成程序。

但是,盡管您的源文件是單獨編譯的,但它們將需要彼此交互。 main.cpp將要創建Odometer對象並訪問Odometer成員函數等等。 因此,我們需要一種方法來告訴main.cpp Odometer是什么。 最簡單的方法是在頭文件中定義Odometer ,並在main.cpp #include該頭。

#include是一個預處理程序指令 ,它將另一個文件的內容插入當前文件。 預處理程序將在實際編譯代碼之前運行。 這個想法是,您在一個文件中有一些聲明,我們將其稱為頭文件,以及需要訪問這些聲明的多個源文件。 因此,每個源文件都會#include標頭。

請注意,盡管main.cpp不需要訪問Odometer成員函數的定義 ,但只需要知道這些函數是什么以及如何調用它們即可。 該信息在odometer.hpp中的類定義中,而不在odometer.cpp #include "odometer.cpp"將會是錯誤的,因為那樣我們將在兩個不同的地方定義函數,並且鏈接器將發出抱怨。

因此,通常將類定義放入頭文件( .hpp )中,將類實現放入源文件( .cpp )中,並將頭文件#include包含在需要訪問該類的任何其他源文件中。 如果以這種方式正確構建你的程序,你應該永遠不需要#include一個.cpp文件到另一個.cpp文件。

如果將odometer.cpp包含在odometer_main.cpp中,則也無法單獨編譯odometer.cpp並將其與odometer_main.cpp鏈接。 是的,是的,您將獲得重復的符號。 但是,通常的方法是只將.hpp文件包含到您的主文件中,而其他所有文件都應編譯並鏈接正常。

這里有多個問題:

里程表

  • Odometer(float g, int m) :在odometer.cpp未定義
  • Odometer() :此默認構造函數也應該在odometer.cpp定義

  • 里程表具有三個成員變量,但是只有兩個作為變量,尚不清楚如何初始化第三個mpg

  • 頭文件中沒有包含保護

    #ifdef ODO_H

    #define ODO_H

    class Odometer{ // your class declaration };

    #endif

里程表

  • #include "odometer.hpp"

  • #include <iostream> -由於您使用的是std::cout

  • 提供各種Odometer構造函數的定義。

main.cpp

  • #include "odometer.hpp" -因為您在這里使用里程表類

解決這些問題應有助於您編譯代碼。

重要的是要使用文件排除指令以避免多次包含。

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

看一下這個問題:

為什么在C ++頭文件中使用#ifndef和#define

就像大家評論的那樣,您應該包括h文件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM