【问题标题】:Compiling error in C++ [closed]C ++中的编译错误[关闭]
【发布时间】:2016-05-03 17:58:52
【问题描述】:

我在这个项目的最后,我得到这个我无法弄清楚的编译错误。这让我发疯,我读到这可能是类之间链接错误的问题。但我不知道它可能在哪里以及如何修复它。

> 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;
}

ma​​in.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;
}

【问题讨论】:

  • 您正在执行什么命令来生成该错误文本?
  • 心理调试器说:CruiseShip.cpp 和 CruiseShip.cpp 在你的 make 文件中有两次
  • “我在这个项目的结尾” 很有趣。当你在编译,并且有一堆链接错误时,你还没有走到尽头。我会说你不到 1/2 的方式来完成。
  • 您在 cargoship.cpp 文件的 CargoShip 的构造函数中遗漏了几个参数,这就是为什么您得到最后一个错误 undefined reference to CargoShip::CargoShip..
  • 另外:基类 Ship 中没有虚拟析构函数,并且您的 Ship 构造函数错误,它应该使用传递的参数进行初始化

标签: c++ inheritance polymorphism


【解决方案1】:

在您的 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-&gt;

我在您的 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];
}

顺便说一句,由于虚拟析构函数,正确的析构函数将被调用。

【讨论】:

  • 添加析构函数修复它,谢谢!
【解决方案2】:

由于缺乏 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 个参数,字符串、字符串和 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

【讨论】:

  • 看来我的 ship.cpp 和 ship.h 编译正常,但编译器却为 CruiseShip 抛出错误?
  • 没有 .它会在您启动应用程序之后或当您启动应用程序时引发错误。我给了你如何正确写作的样本,看看我先给你的是什么
  • 好的,我很感激。
  • 你的 main 很糟糕,因为Ship *ships[3]={ new Ship("Lolipop", "1960"), new CruiseShip("Disney Magic","2010",2400), new CargoShip("Black Pearl","2003",50000) }; 没有任何意义。您应该首先重载 operator= .. 我将编辑我的答案
  • 告诉我你是否有和我一样的输出,因为我在这方面花了很多时间。试着了解我改变了什么
【解决方案3】:

首先,在 CargoShip.cpp 中,您的一些实现缺少 CargoShip::

例如

int getCapacity(){
    return cargoCapacity;
}

应该是

int CargoShip::getCapacity(){
     return cargoCapacity;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 1970-01-01
    • 2013-06-21
    • 2014-02-12
    • 1970-01-01
    相关资源
    最近更新 更多