虚函数和纯虚函数的用法和区别

学习C++的多态,必然听说过虚函数和纯虚函数。
要学习虚函数和纯虚函数,首先我们要搞清楚它的语法规范。总结一下无非下面几点:

  • 在类成员方法的声明(注意不是定义)前面加个virtual,该函数就变为虚函数,在虚函数声明语句后面加个=0,虚函数就变为纯虚函数。
  • 当类中有了纯虚函数,这个类也称为抽象类
  • 子类可以重新定义基类的虚函数,我们把这个行为称之为复写(override)
  • 子类可自主选择是否要提供一份属于自己的个性化虚函数实现,但是必须提供一份属于自己的个性化纯虚函数实现。

虚函数和纯虚函数出现的意义何在呢,我们用一个例子来说明它们是如何实现多态的:

假设我们设计一个饮品做法的类,并提供类似冲泡材料,冲泡时间的实现代码,而饮品的样式也是多种多样,有茶水,咖啡,奶茶等等。然后我们假设有一个饮品制造者,他可以做很多样式的饮品。

首先我们假设所有的饮品做法都有冲泡的水,冲泡材料,冲泡时间。我们将这三种行为抽象到一个抽象类中,并由它来派生具体的饮品。

class AbstractDrinking
{
public:
	//冲泡的水
	virtual void Water();
	//冲泡时间
	virtual void Time() = 0;
	//冲泡材料
	virtual void Ingredients() = 0;

	void MakeDrink() {
		Water();
		Time();
		Ingredients();
	}
};

由此我们有了AbstractDrinking这个基类,当中有冲泡的水,冲泡材料,冲泡时间三个行为和一个执行流程函数,其中冲泡的水是虚函数,而另外两个是纯虚函数。

Water()是一个普通虚函数,基类希望子类提供自己的个性化实现代码,但基类同时也提供一个缺省的虚函数实现版本,在子类不复写该虚函数的情况下作为备选方案

void AbstractDrinking::Water() {
	cout << "200ml纯净水。" << endl;
}

然后根据这个AbstractDrinking基类,我们可以派生出其他各种各样的饮料派生类。

茶类定义

class Tea : public AbstractDrinking
{
	//这里我们复写了纯虚函数Time,Ingredients和虚函数Water
	virtual void Water() {
		cout << "250ml农夫山泉。" << endl;
	}

	virtual void Time() {
		cout << "10min。" << endl;
	}

	virtual void Ingredients() {
		cout << "龙井" << endl;
		cout << "-----------------------" << endl;
	}
};

咖啡类定义

class Coffee : public AbstractDrinking
{
	//这里我们复写了纯虚函数Time和Ingredients,而没有复写虚函数Water
	virtual void Time() {
		cout << "5min。" << endl;
	}

	virtual void Ingredients() {
		cout << "咖啡、牛奶、方糖。" << endl;
		cout << "-----------------------" << endl;
	}
};

以上代码可以看到,咖啡类没有复写Water而是使用基类提供的Water。

然后我们来定义一个优秀的饮品制造者。

class DrinkingMaker
{
public:
	void DoWork(AbstractDrinking * drink) {
		drink->MakeDrink();
		delete drink;
	}
};

然后再在主函数当中实现:

int main()
{
	DrinkingMaker Jack;
	Jack.DoWork(new Coffee);
	Jack.DoWork(new Tea);

	system("pause");
	return 0;
}

总结一下:
当基类的某个成员方法,在大多数情形下由子类提供个性化实现,但基类也可以提供一个备选方案的时候,将其设计为虚函数。
当基类的某个成员方法,必须由子类提供个性化实现的时候,将其设计为纯虚函数。
纯虚函数在基类中的实现跟多态性无关,它只是提供了一种语法上的便利,在变化多端的应用场景中留有后路。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值