[英]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.cpp
和odometer.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
看一下這個問題:
就像大家評論的那樣,您應該包括h文件
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.