用子类覆盖基类中定义的函数

时间:2018-10-23 02:32:10

标签: c++ inheritance

我是C ++的新手,正在尝试了解这种语言的继承。我创建了一个Ship类,定义了一些构造函数,更改器和一个print函数,该函数应该cout有关飞船的一些信息。我有两个派生类,一个是Cruise类,另一个是Cargo类。我第一次编译Cruise类的测试时,一切正常。在实现Cargo类之后,我无法再编译代码。这两个类非常相似,并且实现几乎相同。这是我的代码,我收到的错误在下面。

ship.cpp(定义船级)

#include <iostream>
#include <string>
using namespace std;

class Ship {
private:
    string _strName, _strYear;

public:
    //Constructors
    Ship();
    Ship(string, string);

    //Mutators
    void setName(string);
    void setYear(string);
    string getName();
    string getYear();

    //Methods
    virtual void print();
};

//*************************************
// Cunstructors                       *
//*************************************
Ship::Ship() {
    _strName = "NONE";
    _strYear = "NONE";
}
Ship::Ship(string strname, string strYear) {
    setName(strname);
    setYear(strYear);
}

//*************************************
// MUTATORS                           *
//*************************************
void Ship::setName(string strName) {
    _strName = strName;
}

void Ship::setYear(string strYear) {
    _strYear = strYear;
}

string Ship::getName() {
    return _strName;
}

string Ship::getYear() {
    return _strYear;
}

//*************************************
// METHODS                             *
//*************************************
virtual void Ship::print() {
    cout << _strName << endl
        << _strYear << endl;
}

CuiseShip.cpp(从Ship继承的游轮类)

#include <iostream>
#include <string>
#include "ship.cpp"
using namespace std;

class CruiseShip:public Ship {
private:
    int _intMaxPassengers;

public:
    //Constructors
    CruiseShip();
    CruiseShip(string, string, int);

    //Mutators
    void setMaxPassengers(int);
    int getMaxPassengers();


    //Methods
    void print();
};

//*************************************
// Cunstructors                       *
//*************************************
CruiseShip::CruiseShip() {
    setName("NONE");
    setYear("NONE");
    setMaxPassengers(0);
}
CruiseShip::CruiseShip(string strname, string strYear, int intMaxPassengers) {
    setName(strname);
    setYear(strYear);
    setMaxPassengers(intMaxPassengers);
}

//*************************************
// MUTATORS                           *
//*************************************
void CruiseShip::setMaxPassengers(int intMaxPassengers) {
    _intMaxPassengers = intMaxPassengers;
}

int CruiseShip::getMaxPassengers() {
    return _intMaxPassengers;
}

//*************************************
// METHODS                             *
//*************************************
void CruiseShip::print() {
    string name = getName();
    string year = getYear();
    string maxPassengers = to_string(getMaxPassengers());

    cout << name << endl
        << year << endl
        << maxPassengers << endl;;
}

CargoShip.cpp(来自船的继承)

#include <iostream>
#include <string>
#include "ship.cpp"
using namespace std;

class CargoShip: public Ship {
private:
    int _intCapacity;

public:
    //Constructors
    CargoShip();
    CargoShip(string, string, int);

    //Mutators
    void setCapacity(int);
    int getCapacity();


    //Methods
    void print();
};

//*************************************
// Cunstructors                       *
//*************************************
CargoShip::CargoShip() {
    setName("NONE");
    setYear("NONE");
    setCapacity(0);
}

CargoShip::CargoShip(string strname, string strYear, int intCapacity) {
    setName(strname);
    setYear(strYear);
    setCapacity(intCapacity);
}

//*************************************
// MUTATORS                           *
//*************************************
void CargoShip::setCapacity(int intCapacity) {
    _intCapacity = intCapacity;
}

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

//*************************************
// METHODS                             *
//*************************************
void CargoShip::print() {
    string name = getName();
    string year = getYear();
    string capacity = to_string(getCapacity());

    cout << name << endl
        << year << endl
        << capacity << endl;;
}

TEST.cpp(隐含和测试代码的main())

#include <iostream>
#include <string>
#include "CruiseShip.cpp"
#include "CargoShip.cpp"

int main() {
    CruiseShip cruise("cruise", "1862", 25);
    CargoShip cargo("Mellinium Falcon", "a long time ago", 100);

    cruise.print();
    cargo.print();

    return 0;
}

编译错误

In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:5:7: error: redefinition of ‘class Ship’
 class Ship {
       ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:5:7: error: previous definition of ‘class Ship’
 class Ship {
       ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:27:1: error: redefinition of ‘Ship::Ship()’
 Ship::Ship() {
 ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:27:1: note: ‘Ship::Ship()’ previously defined here
 Ship::Ship() {
 ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:31:1: error: redefinition of ‘Ship::Ship(std::__cxx11::string, std::__cxx11::string)’
 Ship::Ship(string strname, string strYear) {
 ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:31:1: note: ‘Ship::Ship(std::__cxx11::string, std::__cxx11::string)’ previously defined here
 Ship::Ship(string strname, string strYear) {
 ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:39:6: error: redefinition of ‘void Ship::setName(std::__cxx11::string)’
 void Ship::setName(string strName) {
      ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:39:6: note: ‘void Ship::setName(std::__cxx11::string)’ previously defined here
 void Ship::setName(string strName) {
      ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:43:6: error: redefinition of ‘void Ship::setYear(std::__cxx11::string)’
 void Ship::setYear(string strYear) {
      ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:43:6: note: ‘void Ship::setYear(std::__cxx11::string)’ previously defined here
 void Ship::setYear(string strYear) {
      ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:47:8: error: redefinition of ‘std::__cxx11::string Ship::getName()’
 string Ship::getName() {
        ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:47:8: note: ‘std::__cxx11::string Ship::getName()’ previously defined here
 string Ship::getName() {
        ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:51:8: error: redefinition of ‘std::__cxx11::string Ship::getYear()’
 string Ship::getYear() {
        ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:51:8: note: ‘std::__cxx11::string Ship::getYear()’ previously defined here
 string Ship::getYear() {
        ^
In file included from CargoShip.cpp:3:0,
                 from Test.cpp:4:
ship.cpp:58:6: error: redefinition of ‘void Ship::print()’
 void Ship::print() {
      ^
In file included from CruiseShip.cpp:3:0,
                 from Test.cpp:3:
ship.cpp:58:6: note: ‘void Ship::print()’ previously defined here
 void Ship::print() {
      ^

这个错误对我来说几乎没有用,而且我似乎找不到解决方法。编译器似乎告诉我,我正在尝试重新定义Ship类。有人可以解释发生了什么事吗?

1 个答案:

答案 0 :(得分:2)

您永远都不应包含主文件中的.cpp文件。假设#include .cpp文件是一个复制粘贴,并且您将.cpp文件包含在主文件和运送文件中-这将导致这些副本有多个副本,因此您已定义了编译器的内容不止一次。

您必须将类定义放在.h文件中-WITH HEADER GUARDS以防止重复,然后将实现详细信息放在.cpp文件中。示例:

ship.hpp

// Protects from multiple copies
#ifndef _SHIP_H_
#define _SHIP_H_

#include <iostream>
#include <string>
using namespace std;

class Ship {
private:
    string _strName, _strYear;

public:
    //Constructors
    Ship();
    Ship(string, string);

    //Mutators
    void setName(string);
    void setYear(string);
    string getName();
    string getYear();

    //Methods
    virtual void print();
};

#endif // _SHIP_H_

ship.cpp

#include "ship.hpp"    // this .cpp file INCLUDES the .hpp so it can match the functions

//*************************************
// Constructors                       *
//*************************************
Ship::Ship() {
    _strName = "NONE";
    _strYear = "NONE";
}
Ship::Ship(string strname, string strYear) {
    setName(strname);
    setYear(strYear);
}

//*************************************
// MUTATORS                           *
//*************************************
void Ship::setName(string strName) {
    _strName = strName;
}

void Ship::setYear(string strYear) {
    _strYear = strYear;
}

string Ship::getName() {
    return _strName;
}

string Ship::getYear() {
    return _strYear;
}

//*************************************
// METHODS                             *
//*************************************
virtual void Ship::print() {
    cout << _strName << endl
        << _strYear << endl;
}

对其他文件重复相同的操作。

main.cpp

#include <iostream>
#include <string>
#include "CruiseShip.hpp"   // include .hpp files. Linker will link the .hpp functions with the .cpp implementations.
#include "CargoShip.hpp" // same here

int main() {
    CruiseShip cruise("cruise", "1862", 25);
    CargoShip cargo("Mellinium Falcon", "a long time ago", 100);

    cruise.print();
    cargo.print();

    return 0;
}

要生成,必须单独编译所有.cpp文件,以确保它们没有名称冲突。它们将自动与main.cpp链接:

g ++ --std = c ++ 0x ship.cpp cargo.cpp main.cpp ...等等等