在派生 class 的基础 class 构造函数中使用覆盖函数

Using overriden function in base class constructor for derived class

我是 C++ 编程的新手,所以我想编写一些简单的代码来熟悉语法。我暂时故意忽略了指针和引用。

在编码过程中,我在练习继承,我想创建一个 class Hand 代表一手牌。基础 class 有一个名为 update() 的函数,用于在构造时初始化 "total" 和 "notation" 属性。此外,可以使用 add() 函数将卡片添加到手中,该函数将卡片添加到手中并触发 update() 以适当地更新属性。

#include<vector>

class Hand
{
public:
    std::vector<int> cards;
    int total;
    std::string notation; // Abbreviated notation of the object
    // Constructor
    Hand(std::vector<int> cards);
    void update();
    void add(int card);
}

Hand::Hand(std::vector<int> cards)
{
    this->cards = cards;
    update();
}

void Hand::update()
{
    total = 0;
    notation += "{ ";
    for (int card: cards)
    {
        total += card;
        notation += std::to_string(card) + " ";
    }
    notation += "}";
}

void Hand::add(int card)
{
    cards.push_back(card);
    update();
}

接下来,我想创建一个更具体的 class Hand,称为 StandHand,它的功能与 Hand 相同,但它还有一个变量,当总数达到特定值时会发生变化。

一开始我以为我可以像下面这样写subclass,但是唉

class StandHand : public Hand
{
public:
    int stand;
    StandHand(std::vector<int> cards, int stand);
    void update();
}

StandHand::StandHand(std::vector<int> cards, int stand) : Hand(cards)
{
    this->stand = stand;
    updateHand();
}

void StandHand::update()
{
    Hand::update();
    notation += stand <= total ? " (stand)" : "";
}

但是当我在 StandHand 对象上调用 add() 方法时,它没有使用 StandHand::update() 方法,而是使用基本的 update() 方法。如何确保 add() 方法在 Hand 的 subclass 中使用该 subclass?

的 update() 函数

对于初学者来说,代码中没有重载函数。派生class中update的声明隐藏了基class中同名函数的声明。

由于成员函数add是在基class中声明的,因此函数update的名称也在基class中搜索。

将函数 update 声明为虚函数。

class Hand
{
public:
    // ...
    virtual void update();
};

class StandHand : public Hand
{
public:
    // ///
    void update() override;
};

您的代码中有两个问题,首先需要声明基 class 中的 void update(); virtual,以便编译器知道派生的 classes可能会覆盖它并使用它。

virtual void update();
// add "=0;" if there is no base version of update()

并在派生class中写入

void update() override;
//override is unnecessary but recommended
//it verifies that you do indeed overload a method from a base class

第二个问题,您不能在其基础 class 的构造函数中调用派生 class 的方法。发生的情况是调用虚拟基方法导致调用基版本而不是派生版本。想一想:派生对象尚未构造,但您已经调用了它的方法之一?没有任何意义。