从零开学C++:多态

引言:在我们去购买汽车票的时候,我们总会遇到成人全价,学生打折的情况。不同的对象(成人、学生)进行同一操作(购买车票),得到不同的结果(全价、打折),此时这就是我们多态思想的体现。那么我们如何使用C++实现多态呢?请听我接下来的讲解。

更多有关C++的知识详解可前往个人主页:计信猫

一,虚函数

1,虚函数的定义

        虚函数就是一个被virtual修饰的成员函数,如下所示:

class person
{
	virtual void buy()
	{
		cout << "全价" << endl;
	}
};

2,虚函数的重写

        虚函数重写(覆盖)派生类中有一个与基类的虚函数完全相同的虚函数。此时就可以说是基类的虚函数被子类重写(覆盖)了。 

完全相同:

1,函数的返回值相同

2,函数的名字相同

3,函数的参数相同(只看参数类型)

        如下的例子所示:

class person
{
	virtual void buy()
	{
		cout << "全价" << endl;
	}
};
class student :public person
{
	virtual void buy()
	{
		cout << "打折" << endl;
	}
};

        此时派生类buy函数就重写了基类buy函数

3,虚函数重写的两个例外

(1)协变

        协变的定义是基类虚函数返回基类对象的指针或者引用派生类虚函数返回派生类对象的指针或者引用协变的出现导致了虚函数重写的返回值不同,但是并不会出现报错。如下便是一个协变的试例:

class A
{

};
class B :public A
{

};
class person
{
	virtual A* buy()
	{
		cout << "全价" << endl;
	}
};
class student :public person
{
	virtual B* buy()
	{
		cout << "打折" << endl;
	}
};

(2)析构函数的重写

         在我们编写程序时,更加建议将析构函数写成虚函数的形式,以便应对以下情况:

int main()
{
	A* a = new B;
	delete a;
	return 0;
}

        所以我们可以将AB析构函数进行如下处理:

class A
{
public:
	virtual ~A()
	{

	}
};
class B :public A
{
public:
	virtual ~B()
	{

	}
};

        此时B类析构函数仍然重写了A析构函数,虽然在表面上它们的函数名并不相同,但是在底层处理的时候,其实它们的析构函数名称都被编译器处理为了destructor,因此其实它们的函数名是相同的。

4,override和final

(1)override

        override关键字用于检查派生类的某个虚函数是否重写了基类的虚函数,如果没有重写,那么在编译阶段就会发生报错。如下所示:

class person
{
	/*virtual void buy()
	{
		cout << "全价" << endl;
	}*/
};
class student :public person
{
	virtual  void buy()override
	{
		cout << "打折" << endl;
	}
};

        此时派生类buy函数并没有发生重写,那么我们的override关键字就会让程序在编译阶段出现报错:

(2)final

        final关键字修饰的虚函数则不能进行重写。如下方式使用:

class person
{
	virtual void buy()final
	{
		cout << "全价" << endl;
	}
};

         那么此时基类personbuy函数就不能被它的派生类重写,不然就会发生报错。

二,多态

        所以有了前边我们所学习的虚函数知识的支持,那么我们就可以实现一个简单的多态了。此时以前边的成人和学生买票为例(成人买票就是全价,学生买票就是打折)。

        在实现多态之前,我们需要遵循一下规则:

1,需使用基类的指针或引用调用虚函数

2,被调用的函数为virtual修饰的(即为虚函数)

        那么我们实现的多态如下:

class person
{
public:
	virtual void buy()
	{
		cout << "成人全价" << endl;
	}
};
class student :public person
{
public:
	virtual void buy()
	{
		cout << "学生打折" << endl;
	}
};
void func(person& obj)
{
	obj.buy();
}
int main()
{
	person p;
	student s;
	func(p);
	func(s);
	return 0;
}

         此时我们代码一走,那么结果如下:

三,纯虚函数

        纯虚函数的定义十分简单,只需要虚函数的声明之后加上=0即可,如下:

virtual void buy()=0

        纯虚函数一般不会进行实现,有声明即可。

四,抽象类

        含有纯虚函数的类即为抽象类,如下的person类就为抽象类

class person
{
public:
	virtual void buy()=0
};

        如果派生类不重写纯虚函数,那么其派生类也为抽象类。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值