在派生类中添加新功能

在“继承简介”课程中,我们曾指出:使用派生类的最大优势之一在于能够复用已编写完成的代码。你可以继承基类的功能,随后添加新的功能、修改既有功能,或隐藏不需要的功能。在接下来的几课中,我们将逐一详细探讨这些操作的具体实现方式。

首先,给出一个简单的基类示例:

#include <iostream>

class Base
{
protected:
    int m_value {};

public:
    Base(int value)
        : m_value { value }
    {
    }

    void identify() const { std::cout << "I am a Base\n"; }
};

接下来,创建一个从 Base 公有继承的派生类。由于我们希望在构造派生类对象时能够设定 m_value 的值,故在派生类构造函数的初始化列表中显式调用基类构造函数:

class Derived: public Base
{
public:
    Derived(int value)
        : Base { value }
    {
    }
};

在派生类中添加新功能

在上述示例中,由于我们拥有 Base 类的源码,因此如有需要,可直接向 Base 类添加功能。

然而,实际开发中常会遇到以下情形:

  • 虽然拥有基类源码,但并不想修改它。例如,你从第三方供应商处购买了一套代码库,却需要额外功能。若直接修改原代码,一旦供应商发布更新,你的改动要么被覆盖,要么必须手动迁移——既耗时又易出错。
  • 甚至根本无法修改基类。例如,标准库中的代码我们无法改动,但可以从这些类派生,再向派生类添加所需功能。对于仅提供头文件、实现已预编译的第三方库亦同理。

无论哪种情况,最佳做法都是派生出自定义类,并在派生类中添加所需功能。

Base 类中明显缺失的是让外部访问 m_value 的手段。我们本可在 Base 类中增加一个访问函数,但为示例起见,将其添加至派生类。由于 m_value 在 Base 中被声明为 protected,派生类可直接访问。

要向派生类添加新功能,只需像平常一样在派生类中声明即可:

class Derived: public Base
{
public:
    Derived(int value)
        : Base { value }
    {
    }

    int getValue() const { return m_value; }
};

现在,外部代码便可通过 Derived 对象调用 getValue() 以获取 m_value 的值:

int main()
{
    Derived derived { 5 };
    std::cout << "derived has value " << derived.getValue() << '\n';

    return 0;
}

运行结果:

derived has value 5

需要明确指出的是,Base 类型的对象无法使用派生类中的 getValue() 函数。下述代码无法通过编译:

int main()
{
    Base base { 5 };
    std::cout << "base has value " << base.getValue() << '\n';

    return 0;
}

> 原因在于 Base 类中并无 getValue() 成员函数;该函数属于 Derived。Derived 是一种 Base,因此 Derived 可访问 Base 的成员;但 Base 却无法访问 Derived 的任何成员。

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"