代码之家  ›  专栏  ›  技术社区  ›  Gary Willoughby

在不使用虚拟关键字的情况下,如何重写C++继承的成员函数?

  •  1
  • Gary Willoughby  · 技术社区  · 14 年前

    我有一个小程序来演示简单的继承。我正在定义一个从哺乳动物衍生出来的狗类。两个类共享一个名为ToString()的简单成员函数。当我不使用虚拟关键字时,Dog如何覆盖哺乳动物类中的实现?(我是否需要使用虚拟关键字来重写成员函数?)

    哺乳动物,H

    #ifndef MAMMAL_H_INCLUDED
    #define MAMMAL_H_INCLUDED
    
    #include <string>
    
    class Mammal
    {
        public:
            std::string ToString();
    };
    
    #endif // MAMMAL_H_INCLUDED
    

    哺乳动物CPP

    #include <string>
    #include "mammal.h"
    
    std::string Mammal::ToString()
    {
        return "I am a Mammal!";
    }
    

    狗,H

    #ifndef DOG_H_INCLUDED
    #define DOG_H_INCLUDED
    
    #include <string>
    #include "mammal.h"
    
    class Dog : public Mammal
    {
        public:
            std::string ToString();
    };
    
    #endif // DOG_H_INCLUDED
    

    多氯联苯

    #include <string>
    #include "dog.h"
    
    std::string Dog::ToString()
    {
        return "I am a Dog!";
    }
    

    主CPP

    #include <iostream>
    #include "dog.h"
    
    using namespace std;
    
    int main()
    {
        Dog d;
        std::cout << d.ToString() << std::endl;
        return 0;
    }
    

    输出

    I am a Dog!
    

    我正在通过code::blocks在Windows上使用mingw。

    3 回复  |  直到 13 年前
        1
  •  8
  •   CB Bailey    14 年前

    它不是 压倒一切 这个 ToString 基类中的方法,因为基类方法不是 virtual . 它只是用具有相同签名的函数隐藏该函数。

    当你打电话 ToString() 在一 Dog 对象 Dog::ToString 方法被调用。为什么要叫其他的 托斯特林() 方法; Dog:: 声明是第一个找到的吗? 事实上的 只有通过指向基类对象的指针或引用调用分派时才会发生(并且只需要进行分派)。

    如果需要对Dog对象调用基类方法,则必须显式限定它。

    d.Mammal::ToString()
    
        2
  •  8
  •   Jerry Coffin    14 年前

    您的代码直接使用Dog对象,因此当您调用 ToString() ,它静态地绑定到 Dog::ToString() 并产生“我是一只狗!”.

    要演示多态性,可以从指向基类的指针(或引用)开始,但将其设置为引用派生类的对象:

    Dog d;
    Mammal &m = d;
    
    std::cout << m.ToString(); // will produce "I am a Mammal!".
    std::cout << d.ToString(); // will produce "I am a Dog!"
    

    以这种方式调用,如果 ToString 虚拟的,输出将取决于指向的对象的类型,而不是指针/引用本身的类型(因此上面的两个调用都会产生“我是一条狗!”).

        3
  •  1
  •   Brad Larson    13 年前

    尝试在添加虚拟 ToString() 类哺乳动物的方法。我想这就是你想要的。

    class Mammal
    {
        public:
            virtual std::string ToString();
    };