我有一个小程序来演示简单的继承.我正在定义一个源自哺乳动物的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.
它不会覆盖ToString基类中的方法,因为基类方法不是virtual.它只是使用具有相同签名的函数隐藏该函数.
当你调用ToString()一个对Dog对象的Dog::ToString方法被调用.为什么要调用任何其他ToString()方法; 该Dog::声明是第一个发现了什么?virtual当通过指针或对基类对象的引用调用时,dispatch只会发生(并且只需要).
如果需要在Dog对象上调用基类方法,则必须明确限定它.
d.Mammal::ToString()
Run Code Online (Sandbox Code Playgroud)
您的代码直接使用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虚拟,输出将取决于指向的对象的类型而不是指针/引用本身的类型(因此上面的两个调用都会产生"我是狗!").