如果没有使用虚拟关键字,我如何重写此C++继承的成员函数?

Gar*_*hby 1 c++ inheritance

我有一个小程序来演示简单的继承.我正在定义一个源自哺乳动物的Dog类.这两个类共享一个名为ToString()的简单成员函数.当我没有使用虚拟关键字时,Dog如何覆盖Mammal类中的实现?(我甚至需要使用virtual关键字来覆盖成员函数吗?)

mammal.h

#ifndef MAMMAL_H_INCLUDED
#define MAMMAL_H_INCLUDED

#include <string>

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

#endif // MAMMAL_H_INCLUDED
Run Code Online (Sandbox Code Playgroud)

mammal.cpp

#include <string>
#include "mammal.h"

std::string Mammal::ToString()
{
    return "I am a Mammal!";
}
Run Code Online (Sandbox Code Playgroud)

dog.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
Run Code Online (Sandbox Code Playgroud)

dog.cpp

#include <string>
#include "dog.h"

std::string Dog::ToString()
{
    return "I am a Dog!";
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include <iostream>
#include "dog.h"

using namespace std;

int main()
{
    Dog d;
    std::cout << d.ToString() << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量

I am a Dog!
Run Code Online (Sandbox Code Playgroud)

我通过Code :: Blocks在Windows上使用MingW.

CB *_*ley 8

它不会覆盖ToString基类中的方法,因为基类方法不是virtual.它只是使用具有相同签名的函数隐藏该函数.

当你调用ToString()一个对Dog对象的Dog::ToString方法被调用.为什么要调用任何其他ToString()方法; 该Dog::声明是第一个发现了什么?virtual当通过指针或对基类对象的引用调用时,dispatch只会发生(并且只需要).

如果需要在Dog对象上调用基类方法,则必须明确限定它.

d.Mammal::ToString()
Run Code Online (Sandbox Code Playgroud)


Jer*_*fin 8

您的代码直接使用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!"
Run Code Online (Sandbox Code Playgroud)

这样调用,如果你创建ToString虚拟,输出将取决于指向的对象的类型而不是指针/引用本身的类型(因此上面的两个调用都会产生"我是狗!").