我是类和面向对象编程的新手。我们的教师让我们创建一个必须包含.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
答案 0 :(得分:1)
简而言之,将#include "odometer.cpp"
替换为#include "odometer.hpp"
。现在为什么。
您的计划包含main.cpp
和odometer.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文件