C++开发中级


930 浏览 5 years, 10 months

3.3 使用父类方法

版权声明: 转载请注明出处 http://www.codingsoho.com/

使用父类方法

当在子类中重写方法的时候,您有效地替换了原始方法。然而,父类版本的方法仍然存在,您仍然可以使用这些方法。例如,某个重写方法可能除了完成父类实现完成的任务之外,还会完成一些其他任务。考虑WeatherPrediction类中的getTemperature()方法,这个方法返回当前温度的字符串表示:

class WeatherPrediction
{
    public:
        virtual std::string getTemperature() const; 
}

在MyWeatherPrediction类中,可按如下方式重写这个方法:

class MyWeatherPrediction : public WeatherPrediction
{
    public:
        virtual std::string getTemperature() const; 
}

假定子类想要通过这种方法将F添加到字符串中:首先调用超类的getTemperature()方法,然后将F添加到string。您或许想编写如下的代码:

void MyWeatherPrediction::getTemperature() const
{
    return getTemperature() + "F"; // BUG
}

然而,这行代码无法运行,根据C++的名称解析规则,首先解析局部作用域,然后是类作用域,根据这个顺序函数中调用的是MyWeatherPrediction::getTemperature()。其结果是无限递归,直到耗尽堆栈空间(某些编译器在编译时会发现这种错误并报错)。

为了让代码运行,需要使用作用域解析运算符,如下所示:

string MyWeatherPrediction::getTemperature() const
{
    return WeatherPrediction::getTemperature() + "F"; 
}

Microsoft Visual C++支持__super关键字(两条下划线)。这个关健字允许您编写如下的代码:return __super::getTemperature()+”0F”;

在C++中,调用当前方法的父类版本是一种常见的操作。如果存在子类链,每个子类都可能想执行超类中已经定义的操作,同时添加自己的附加功能。

另一个示例是书本类型的类层次结构。下图显示了这个层次结构。

由于层次结构底层的类更具体地指出了书本的类型,获取描述书本描述信息的方法实际上需要考虑层次结构中的所有层次。可以通过连续调用父类方法做到这点,下面的代码演示了这一模式。代码中还定义了一个virtual getHeight()方法,这个方法在该示例之后将进一步讨论。

class Book
{
    public:
        virtual string getDescription(){ return "Book"; }
        virtual int getHeight() { return 120; }
}

class Paperback : public Book
{
    public:
        virtual string getDescription(){
            return "Paperback " + Book::getDescription();
        }
}

class Romance : public Paperback
{
    public:
        virtual string getDescription(){
            return "Romance " + Paperback::getDescription();
        }
        virtual int getHeight(){ return Paperback::getHeight() / 2; }
}

class Technical : public Book
{
    public:
        virtual string getDescription(){
            return "Technical " + Book::getDescription();
        }
}

int main()
{
    Romance novel;
    Book book;
    cout << novel.getDescription() << endl; // Outputs "Romance Paperback Book"
    cout << book.getDescription() << endl;  // Outputs "Book"
    cout << novel.getHeight() << endl;      // Outputs "60"
    cout << book.getHeight() << endl;       // Outputs "120"
    return 0;
}

Book类定义了一个virtual getHeight()方法,返回120。只有Romance类重写了这个方法:调用了父类(Paperback)的getHeight(),然后将结果除以2,如下所示:

virtual int getHeight(){ return Paperback::getHeight() / 2; }

然而,Paperback没有重写getHeight(),因此C++会沿着类层次结构向上寻找实现了getHeight()的类。在前面的示例中,Paperback::getHeight()将被解析为Book::getHeight()。