我正在介绍C++类,我正试图找出为什么我会遇到"调用没有匹配的函数"错误。我也看过其他帖子,但这些似乎主要是构造函数本身的问题。
这是简化的片段:
在基本类-船舶
// Members: shipName, shipBuiltYear
Ship::Ship(){ //implementation }
Ship::Ship(string name, string year){ //implementation }
void Ship::set(string name, string year){ //implementation }
衍生类-海盗船
// Members: numPirates
PirateShip::PirateShip() : Ship() { //implementation }
PirateShip::PirateShip(string name, string year, string pirates) : ship(name, year){ //implementation }
void PirateShip::set(int pirates){ //implementation }
在主中
Ship *ships[2] = {new Ship(), new PirateShip()};
ships[0] -> set("Luvinia", "2020"); // using setter from base class
ships[1] -> set("Skylin", "2030"); // using setter from base class
ships[1] -> set(100); // using setter from derived class
问题是你不能用基类设置海盗船,然后用海盗船再次设置吗?
我必须换吗:
void PirateShip::set(int pirates){ //implementation }
至:
void PirateShip::set(string name, string year, string pirates)
{
Ship::set(name, year);
numPirates = pirates;
}
或者有其他方法可以做到这一点吗?
这里有两个问题。
第一:
Ship *ships[2] = {new Ship(), new PirateShip()};
这是指向两个对象的CCD_ 1部分的指针数组。第一个是一个Ship
,第二个是PirateShip
。但是你只有一个指向PirateShip
的Ship
部分的指针,所以只能(直接(与它交互
如果Ship
有虚拟方法,那么您可以使用RTTI和dynamic_cast
来查询给定的Ship*
是否指向Ship
0的Ship
部分,如下所示:
auto* pirate = dynamic_cast<PirateShip*>(some_ship);
如果pirate
不为空,则some_ship
指向PirateShip
的Ship
段。
请注意,使用动态强制转换是代码气味;这可能意味着您应该改进基类接口,或者在这里没有指向基类的指针。
第二部分是,如果你想从PirateShip*
调用Ship::set
,你需要添加
using Ship::set;
至CCD_ 17的主体。
如果知道元素是特定类型(并且必须知道如果使用其特定参数要求进行调用(,则可以将强制转换为适当的类型:
Ship* ships[2] = {new Ship(), new PirateShip()};
ships[0] -> set("Luvinia", "2020"); // using setter from base class
ships[1] -> set("Skylin", "2030"); // using setter from base class
dynamic_cast<PirateShip*>(ships[1]) -> set(100); // change to the correct interface
然而,我会质疑这里的设计。为了使多态性正常工作,您不需要知道创建后子类的确切类型。
也许将初始化调用作为构造函数的一部分?或者在将对象添加到数组之前配置对象?
也
现在,使用指向自己的对象的原始指针被认为不是一种好做法。我推荐智能指针:
std::unique_ptr<Ship> ships[2];
同样,在大多数情况下,使用内置阵列也不太理想。考虑std::vector
:
std::vector<std::unique_ptr<Ship>> ships;
或者如果你想要固定大小的std::array
:
std::array<std::unique_ptr<Ship>, 2> ships;