c++第五次作业:重载与多态

c++重载与多态

1:多态的概述:

在c++中,多态指的是在消息被不同类型的对象接受时导致的不同行为,而消息指的是对类的成员函数的调用,不同的行为也指的是不同的实现,也就是调用了不同的函数,并且多态在程序设计中经常被使用。

2:多态的实现:

多态实现基本分为两类,编译时的多态和运行时的多态,前者是在编译过程中确定了同名操作的具体操作步骤二后者是在程序运行过程中才动态的确定操作指针的具体对象。

3:运算符号的重载:

我们知道在c++中你可以把两个int类型的数据直接相加也可以把两个float型的数据相加,加上我们前段时间所学习的函数重载方面的知识,那么我们可不可以把运算符号重载并且直接利用重载后的运算符将两个类直接相加呢?答案当然是可以的,下面我们来先具体看一个例子

#include<iostream>
using namespace std;
class counter {
public:counter operator+ (counter &a1);
	   counter(int a1, int b1) :a(a1), b(b1) {};
	   void show() { cout << "("<<a <<"," << b <<")"<< endl; }
private: int a, b;
};

counter counter::operator+ (counter &a1)
{
	return counter(a + a1.a, b + a1.b);
}

void main()
{
	counter a(3, 4);
	a.show();
	counter b(1, 1),c(0,0);
	b.show();
	c=a + b;
	c.show();
}

如上图所示的代码,在上面的代码中,我们将运算符“+”进行了重载,在重载后即可直接在两个类中间使用+好把两个类进行相加,运行后结果如下图所示

可以看到通过相加后确实将前两个类的值合并到了第三个类中,在上面的代码中运算符重载函数是在第一个类中声明的,那么是不是可以将重载函数声明在类的外面并且用友元进行实现呢我们再看下面的代码

#include<iostream>
using namespace std;
class point{
public: friend point operator+ (point &t2,point &t1);
		point(int a, int b) :x(a), y(b) {};
		void show() {
			cout << "("<<x << "," << y<<")" << endl;
		}
private: int x, y;
};

 point operator+ (point &t2, point &t1) {
	return point(t2.x + t1.x, t2.y + t1.y);
};

void main()
{
	point a(5, 5), b(6, 6), c(0, 0);
	a.show();
	b.show();
	c = a + b;
	c.show();
}

再继续看上面所示的代码我们将重载函数定义在类的外面,然后声明友元函数,具体运行后截图在下面进行展示

如图所示也同样实现了应有的功能,这就是运算符的重载

4:虚函数及其应用:

虚函数是动态绑定的基础,虚函数是非静态的成员函数。虚函数经过派生之后,在类族中就可以实现运行过程中的多态。

4.1:一般虚函数成员

虚函数声明语法是 virtual 函数类型 函数名(形参名)

函数声明只能在定义时而不是在成员函数实现的时候。

#include<iostream>
using namespace std;
class mammal {
public:virtual void speak() {
		cout << "哺乳动物" << endl;
	}
};

class dog :public mammal {

public: void speak() {
	cout << "狗" << endl;
}
};
class pig:public dog {
public: void speak() {
	cout << "猪" << endl;
}
};
void fun(mammal *a)
{
	a->speak();
}

void main()
{
	mammal c;
	dog a;
	pig b;

	fun(&c);
	fun(&a);
	fun(&b);
}

如上图所示代码,运行结果如下

这里再把virtual去掉的代码结果用于比较

从输出的结果来看,mammal dog pig 都是属于同一个类族,并且dog 与pig都是通过公共派生而来,并且基类mammal中的函数speak()定义为虚函数,在程序中又使用对象的指针来访问函数成员,这样的话绑定就会在运行中完成,实现了运行中的多态,通过了基类的指针就可以访问到正在只想的对象成员,这样就可以对类族中的对象统一处理,使程序更加简洁高效。

4.2:纯虚函数:

纯虚函数是一个在基类中声明的虚函数,他在基类中没有具体的定义和操作,声明为纯虚函数后,基类中就可以不再给出函数的实现部分,它的声明为 virtual 函数类型 函数名(参数表)=0;

在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。所以这里才会用到纯虚函数,它的用法和虚函数基本相同,这里不再给与过多重复的展示。

4.3:抽象类:

带有纯虚函数的类即为抽象类,抽象类是不能实例化的,它的主要作用是通过他为一个类族建立一个公共的接口,使他们能够更有效的发挥多态的特性,抽象类声明了一个接口,而接口的实现要由派生类自己定义

这里讲究上一个代码改为抽象类给予展示

#include<iostream>
using namespace std;
class mammal {
public: virtual void speak()= 0;
};

class dog :public mammal {

public: void speak() {
	cout << "狗" << endl;
}
};
class pig:public dog {
public: void speak() {
	cout << "猪" << endl;
}
};
void fun(mammal *a)
{
	a->speak();
}

void main()
{
	
	dog a;
	pig b;
	fun(&a);
	fun(&b);
}

稍作修改即成为了抽象类,运行结果如下

这里就是抽象类的具体展示

以上就为我理解的重载与多态的内容,如有错误请斧正。

posted @ 2019-10-26 20:52  不见风雨不见你  阅读(239)  评论(0编辑  收藏  举报