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

overiding functions defined in a base class with a child class

本文关键字:定义 函数 基类 子类 覆盖      更新时间:2023-10-16

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

船舶.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;;
}

货船.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 类。有人可以解释一下发生了什么吗?

您永远不应该包含主文件中.cpp文件。 想象一下,#including .cpp 文件是复制和粘贴的,并且您将.cpp文件包含在主文件和船文件中 - 这会导致这些副本的多个副本,因此编译器已经多次定义了它。

必须将类定义放在 .h 文件中 - 使用标头保护以防止这种重复,然后将实现详细信息放在.cpp文件中。例:

船.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_

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

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

主.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文件,以确保它们没有名称冲突。它们将自动与主.cpp链接:

g++ --std=c++0x 船舶.cpp货物.cpp主要.cpp ...等等