我在这个项目结束时遇到了这个我无法弄清楚的编译错误。这让我疯了,我读到这可能是一个类之间存在链接错误的问题。但我无法弄清楚它可能在哪里以及如何解决它。
> CruiseShip.o: In function `CruiseShip':
> /home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:8: multiple
> definition of `CruiseShip::CruiseShip(std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >, int)' CargoShip.o:/home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:8:
> first defined here CruiseShip.o: In function `CruiseShip':
> /home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:8: multiple
> definition of `CruiseShip::CruiseShip(std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >, int)' CargoShip.o:/home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:8:
> first defined here CruiseShip.o: In function
> `CruiseShip::setPass(int)':
> /home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:12: multiple
> definition of `CruiseShip::setPass(int)'
> CargoShip.o:/home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:12:
> first defined here CruiseShip.o: In function `CruiseShip::getPass()':
> /home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:15: multiple
> definition of `CruiseShip::getPass()'
> CargoShip.o:/home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:15:
> first defined here CruiseShip.o: In function `CruiseShip::print()':
> /home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:20: multiple
> definition of `CruiseShip::print()'
> CargoShip.o:/home/013/w/wn/wna130030/Assignment5_test/CruiseShip.cpp:20:
> first defined here main.o: In function `main':
> /home/013/w/wn/wna130030/Assignment5_test/main.cpp:18: undefined
> reference to `CargoShip::CargoShip(std::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >, int)'
collect2: ld returned 1 exit status make: *** [app] Error 1
CruiseShip.h
#ifndef CRUISESHIP_H_
#define CRUISESHIP_H_
#include <string>
class CruiseShip: public Ship{
protected:
int maxPassengers;
public:
CruiseShip(std::string name,std::string year, int maxPassengers);
void setPass(int);
int getPass();
virtual void print();
};
#endif
CruiseShip.cpp
#include <iostream>
#include "Ship.h"
#include "CruiseShip.h"
using namespace std;
CruiseShip::CruiseShip(std::string name,std::string year, int maxPassengers):Ship(name,year){
maxPassengers=0;
}
void CruiseShip::setPass(int maxPassengers){
this->maxPassengers=maxPassengers;
}
int CruiseShip::getPass(){
return maxPassengers;
}
void CruiseShip::print(){
cout<<"The name of the ship is "<<getName()<<endl;
cout<<"The capacity of the ship is "<<maxPassengers<<endl;
}
Ship.h
#ifndef SHIP_H_
#define SHIP_H_
#include <string>
class Ship{
protected:
std::string name;
std::string year;
public:
//Default Constructor
Ship(std::string name, std::string year);
void setName(std::string name);
void setYear(std::string year);
std::string getName();
std::string getYear();
virtual void print();
};
#endif
Ship.cpp
#include <iostream>
#include "Ship.h"
using namespace std;
Ship::Ship(string name, string year){
name="";
year = "";
}
void Ship::setName(string name){
this->name = name;
}
void Ship::setYear(string year){
this->year=year;
}
string Ship::getName(){
return name;
}
string Ship::getYear(){
return year;
}
void Ship::print(){
cout<<"The name of the ship is "<<name<<endl;
cout<<"The year the ship was built is "<<year<<endl;
}
CargoShip.h
#ifndef CARGOSHIP_H_
#define CARGOSHIP_H_
#include <string>
class CargoShip: public Ship{
protected:
int cargoCapacity;
public:
CargoShip(std::string name, std::string year,int cargoCapacity);
int getCapacity();
virtual void print();
};
#endif
CargoShip.cpp
#include <iostream>
#include "Ship.h"
#include "CruiseShip.h"
#include "CargoShip.h"
using namespace std;
CargoShip::CargoShip(int cargoCapacity):Ship(name,year){
this->cargoCapacity=cargoCapacity;
}
int getCapacity(){
return cargoCapacity;
}
void print(){
cout<<"The Name of the ship is "<<getName()<<endl;
cout<<"The ship's cargo capacity is "<<cargoCapacity<<endl;
}
的main.cpp
#include <iostream>
#include <iomanip>
#include "Ship.h"
#include "CruiseShip.h"
#include "CargoShip.h"
using namespace std;
int main()
{
int i;
//An array of Ship pointers
Ship *ships[3]={
new Ship("Lolipop", "1960"),
new CruiseShip("Disney Magic","2010",2400),
new CargoShip("Black Pearl","2003",50000)
};
//Display output
for(i=0;i<3;i++){
ships[i]->print();
}
return 0;
}
答案 0 :(得分:2)
在你的CargoShip.cpp中你有一些功能,你忘记了前面的课程名称:
int getCapacity(){
return cargoCapacity;
}
void print()
{
cout<<"The Name of the ship is "<<getName()<<endl;
cout<<"The ship's cargo capacity is "<<cargoCapacity<<endl;
}
应该是
int CargoShip::getCapacity() // you may want to add const here too
{
return cargoCapacity;
}
...
您还可以在CargoShip.cpp中包含Cruiseship.h和CargoShip.h 原因。
其他一些事情:
你的构造函数看起来有点偏,用它们来初始化成员变量
Ship::Ship(string name, string year)
{
name="";
year = "";
}
应该是
Ship::Ship(string name, string year)
{
this->name=name;
this->year = year;
}
并且最好使用其他名称作为参数以避免this->
我在您的Ship类中看不到虚拟析构函数,否则在您删除对象时会遇到严重问题。
在派生类头中包含基类也是更好的样式。这样,当用户使用您的派生类头时,他不需要知道之前要包含的头。
#ifndef CRUISESHIP_H_
#define CRUISESHIP_H_
#include <string>
#include "Ship.h" <--
class CruiseShip: public Ship
{
当您从不修改成员变量的函数返回值时,将其声明为const:
...
int getPass() const;
...
当您声明一个这样的数组时,它是一个很好的样式,当你完成它时你也要清理它
//An array of Ship pointers
Ship *ships[3]={
new Ship("Lolipop", "1960"),
new CruiseShip("Disney Magic","2010",2400),
new CargoShip("Black Pearl","2003",50000)
};
...
for (int i = 0; i < 3; ++i)
{
delete ships[i];
}
btw是因为虚拟析构函数将调用正确的析构函数。
答案 1 :(得分:0)
由于缺乏C ++知识,您的代码中存在许多错误。我将尝试解释您Ship
文件中的错误。
Ship.h
#ifndef SHIP_H_
#define SHIP_H_
#include <iostream>
#include <string>
class Ship{
private: // should be private because you just want your class to access them
std::string name;
std::string year;
public:
/* default constructor because this is what is walled when you just create a variable like : Ship ship1;*/
Ship();
Ship(std::string, std::string); //constructor with parameters
// SETTERS
void setName(const std::string);
void setYear(const std::string);
//GETTERS
std::string getName() const;
std::string getYear() const;
virtual void print() const; // virtual class
};
#endif
Ship.cpp
#include "Ship.h"
using namespace std;
Ship::Ship(){
name="";
year="";
}
Ship::Ship(string name, string year){
this->name=name;
this->year = year;
}
// SETTERS
void Ship::setName(const string name){
this->name = name;
}
void Ship::setYear(const string year){
this->year=year;
}
// GETTERS
string Ship::getName()const{
return name;
}
string Ship::getYear()const{
return year;
}
void Ship::print()const{
cout<<"The name of the ship is "<<getName()<<endl;
cout<<"The year the ship was built is "<<getYear()<<endl;
}
const函数告诉程序它不能修改变量。 getter不应该修改类参数。在你的例子中它是显而易见的,但它是强制它的好方法。 Const变量是相同的,您传入参数的变量不能被修改。
存在4种不同的构造函数。默认值与具有参数的构造函数不同。带参数的构造函数在这里用参数覆盖类的参数。
对于cargoShip,当你声明CargoShip(std::string, std::string,int)
时你有3个参数,string,string和int。当您使用它时,您必须使用相同的名称和相同数量和类型的参数调用该函数,否则它将不会调用相同的函数:
CargoShip::CargoShip(string name, string year,int cargoCapacity):Ship(name,year){
// Ship constructor is called givind the parameters name and year
this->cargoCapacity=cargoCapacity;
}
的main.cpp
int main()
{
Ship *ship=new Ship("Lolipop", "1960");
CruiseShip *cruiseShip=new CruiseShip("Disney Magic","2010",2400);
CargoShip *cargoShip=new CargoShip("Black Pearl","2003",50000);
//Display output
Ship *ships[3]={ship,cruiseShip,cargoShip}; // THIS is a really bad way to do it
for(int i=0;i<3;i++){
ships[i]->print();
}
return 0;
}
给我:
The name of the ship is Lolipop
The year the ship was built is 1960
The name of the ship is Disney Magic
The capacity of the ship is 0
The ship's cargo capacity is 50000
答案 2 :(得分:-1)
首先,在CargoShip.cpp中,你的一些实现缺少CargoShip ::
例如
int getCapacity(){
return cargoCapacity;
}
应该是
int CargoShip::getCapacity(){
return cargoCapacity;
}