虚函数(Virtual Function)与 纯虚函数(Pure Virtual Function)

1>虚函数(Virtual Function)

1.1>Base Class

#ifndef Animal_h
#define Animal_h
#include <string>
class Animal
{
protected:
	std::string m_strName;

	// We're making this constructor protected because
	// we don't want people creating Animal objects directly,
	// but we still want derived classes to be able to use it.
	Animal(std::string strName): m_strName(strName)
	{
	}

public:
	std::string GetName() { return m_strName; }
	virtual const char* Speak() { return "???"; }
	//virtual const char* Speak()=0;
};

#endif

1.2>Derived Class 1

#ifndef Cat_h
#define Cat_h
#include"Animal.h"
class Cat: public Animal
{
public:
	Cat(std::string strName): Animal(strName)
    {
    }
 
    virtual const char* Speak() { return "Meow"; }
};
#endif

1.3>Derived Class 2

#ifndef Dog_h
#define Dog_h
#include"Animal.h"
class Dog: public Animal
{
public:
    Dog(std::string strName) : Animal(strName)
    {
    }
 
    virtual const char* Speak() { return "Woof"; }
};
#endif

1.4>Main Class

#include<iostream>
#include"Cat.h"
#include"Dog.h"
using namespace std;
int main(){

	Cat cCat("cat");
	
	cout<<cCat.GetName()<<" says "<<cCat.Speak()<<endl;
	Dog cDog("dog");
	cout<<cDog.GetName()<<" says "<<cDog.Speak()<<endl;

	return 0;
}

Result is:


运行结果正常。

1.5>Derived Class 3

#ifndef Cow_h
#define Cow_h
#include"Animal.h"
class Cow: public Animal
{
public:
	Cow(std::string strName): Animal(strName)
    {
    }
 
    // We forgot to redefine Speak
	//virtual const char* Speak(){ return "Moo";}
};
#endif

在这里我们忘记定义Base Class Animal的Speak()函数了。

而Main函数改为下面的形式:

#include<iostream>
#include"Cow.h"
using namespace std;
int main(){
	Cow cCow("cow");
	cout<<cCow.GetName()<<" says "<<cCow.Speak()<<endl;

	return 0;
}

Result is:

What happened? We forgot to redefine Speak, so cCow.Speak() resolved to Animal.Speak(), which isn’t what we wanted.(我们忘记重新定义Speak函数了,所以cCow.Speak()解析为基类Animal的Speak()函数了,这不是我们所期望的。)

A better solution to this problem is to use a pure virtual function:
(解决这个问题的一个更好的方法是使用纯虚函数)

2>纯虚函数(Pure Virtual Function)

将Animal中的Speak()声明改成如下纯虚函数形式:

virtual const char* Speak()=0;

然后重新编译1.5中的程序,出现如下错误:

1>d:\visual studio 2008\projects\cnn_finite_wordlength_emulator\purevirtualfunctiontest\purevirtualfunctiontest\main.cpp(5) : error C2259: 'Cow' : cannot instantiate abstract class
1>        due to following members:
1>        'const char *Animal::Speak(void)' : is abstract
1>        d:\visual studio 2008\projects\cnn_finite_wordlength_emulator\purevirtualfunctiontest\purevirtualfunctiontest\animal.h(19) : see declaration of 'Animal::Speak'

大致意思是:

error C2259 ‘Cow’:不能实例化抽象类  , 因为'const char *Animal::Speak(void)' 是抽象的,请查看'Animal::Speak'的声明。

也就是说,Cow类只有提供Speak的函数实现才可以实例化实例化。

2.1>提供Speak的函数实现

#ifndef Cow_h
#define Cow_h
#include"Animal.h"
class Cow: public Animal
{
public:
	Cow(std::string strName): Animal(strName)
    {
    }
 
    //  Cow provides a body for Speak().
	virtual const char* Speak(){ return "Moo";}
};
#endif


再次编译并运行,结果如下:

A pure virtual function is useful when we have a function that we want to put in the base class, but only the derived classes know what it should return. A pure virtual function makes it so the base class can not be instantiated, and the derived classes are forced to define these function before they can be instantiated. This helps ensure the derived classes do not forget to redefine functions that the base class was expecting them to.


URL:http://www.learncpp.com/cpp-tutorial/126-pure-virtual-functions-abstract-base-classes-and-interface-classes/





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值