向派生类添加新函数
在继承课程的介绍中,我们提到使用派生类的最大好处之一是能够重用已编写的代码。您可以继承基类功能,然后添加新功能,修改现有功能或隐藏您不需要的功能。在接下来的几节课中,我们将仔细研究这些事情是如何完成的。
首先,让我们从一个简单的基类开始:
#include <iostream>
class Base
{
protected:
int m_value;
public:
Base(int value)
: m_value(value)
{
}
void identify() { std::cout << "I am a Base\n"; }
};
现在,让我们创建一个继承自Base的派生类。因为我们希望派生类能够在实例化派生对象时设置m_value的值,所以我们将使Derived构造函数在初始化列表中调用Base构造函数。
class Derived: public Base
{
public:
Derived(int value)
: Base(value)
{
}
};
向派生类添加新功能
在上面的示例中,因为我们可以访问Base类的源代码,所以如果需要,我们可以直接向Base添加功能。
有时我们可以访问基类但不想修改它。考虑刚刚从第三方供应商处购买代码库但需要一些额外功能的情况。您可以添加到原始代码,但这不是最佳解决方案。如果供应商向您发送更新怎么办?您的添加内容将被覆盖,或者您必须手动将其添加到更新中,这既费时又有风险。
或者,有时甚至不可能修改基类。考虑标准库中的代码。我们无法修改标准库中的代码。但是我们能够从这些类继承,然后将我们自己的功能添加到派生类中。对于第三方库,您也可以使用标题,但代码是预编译的。
在任何一种情况下,最好的答案是派生自己的类,并将所需的功能添加到派生类。
Base类中的一个明显遗漏是public访问m_value的一种方式。我们可以通过在Base类中添加一个访问函数来解决这个问题 - 但是为了示例,我们将把它添加到派生类中。由于m_value已在Base类中声明为受保护,因此Derived可以直接访问它。
要向派生类添加新功能,只需在派生类中声明该功能,就像正常一样:
class Derived: public Base
{
public:
Derived(int value)
:Base(value)
{
}
int getValue() { 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类型的对象无法访问Derived中的getValue()函数。以下不起作用:
int main()
{
Base base(5);
std::cout << "base has value " << base.getValue() << '\n';
return 0;
}
这是因为Base中没有getValue()函数。函数getValue()属于Derived。因为Derived是Base派生类,所以Derived可以访问Base中的内容。但是,Base无法访问Derived中的任何内容。