在C ++多态性中,如何避免函数的名称隐藏(调用错误没有匹配的函数)?

时间:2018-12-03 05:51:37

标签: c++ polymorphism

我正在介绍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

问题是您不能使用基类来设置PirateShip,然后再使用PirateShip来设置它?

我必须更改:

void PirateShip::set(int pirates){ //implementation }

收件人:

void PirateShip::set(string name, string year, string pirates)
{ 
    Ship::set(name, year);
    numPirates = pirates; 
}

或者还有另一种方法吗?

2 个答案:

答案 0 :(得分:1)

这里有两个问题。

第一:

Ship *ships[2] = {new Ship(), new PirateShip()};

这是指向两个对象的Ship部分的指针的数组。第一个是Ship,第二个是PirateShip。但是您只有一个指向Ship的{​​{1}}部分的指针,因此只能(直接)与其交互。

如果PirateShip具有虚拟方法,则可以使用RTTI和Ship来查询给定的dynamic_cast是否指向{{1}的Ship*部分}:

Ship

如果PirateShip不为空,则auto* pirate = dynamic_cast<PirateShip*>(some_ship); 指向pirate中的some_ship条。

请注意,使用动态强制转换是代码异味;这可能意味着您应该改进基类接口,或者在这里没有指向基类的指针。


第二部分是,如果您希望能够从Ship呼叫PirateShip,则需要添加

Ship::set

PirateShip*的正文。

答案 1 :(得分:0)

如果知道一个元素是特定类型(并且必须知道如果您要调用其特定参数要求),则可以 < em> cast 设置为适当的类型:

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

但是我会在这里质疑设计。为了使多态性正常工作,您无需在创建后 子类的确切类型。

也许使初始化调用成为构造函数的一部分?还是配置对象之前将它们添加到数组中?

ALSO

如今,

使用指向 own 对象的原始指针并不是一种好习惯。我建议使用智能指针

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;