我有一个小程序来演示简单的继承.我正在定义一个源自哺乳动物的Dog类.这两个类共享一个名为ToString()的简单成员函数.当我没有使用虚拟关键字时,Dog如何覆盖Mammal类中的实现?(我甚至需要使用virtual关键字来覆盖成员函数吗?)
mammal.h
#ifndef MAMMAL_H_INCLUDED #define MAMMAL_H_INCLUDED #includeclass Mammal { public: std::string ToString(); }; #endif // MAMMAL_H_INCLUDED
mammal.cpp
#include#include "mammal.h" std::string Mammal::ToString() { return "I am a Mammal!"; }
dog.h
#ifndef DOG_H_INCLUDED #define DOG_H_INCLUDED #include#include "mammal.h" class Dog : public Mammal { public: std::string ToString(); }; #endif // DOG_H_INCLUDED
dog.cpp
#include#include "dog.h" std::string Dog::ToString() { return "I am a Dog!"; }
main.cpp中
#include#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.
它不会覆盖ToString
基类中的方法,因为基类方法不是virtual
.它只是使用具有相同签名的函数隐藏该函数.
当你调用ToString()
一个对Dog
对象的Dog::ToString
方法被调用.为什么要调用任何其他ToString()
方法; 该Dog::
声明是第一个发现了什么?virtual
当通过指针或对基类对象的引用调用时,dispatch只会发生(并且只需要).
如果需要在Dog对象上调用基类方法,则必须明确限定它.
d.Mammal::ToString()
您的代码直接使用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
虚拟,输出将取决于指向的对象的类型而不是指针/引用本身的类型(因此上面的两个调用都会产生"我是狗!").