c++第五次作业:关于多态

关于多态

一、什么是多态

同样的消息被不同类型的对象接收时导致的不同的行为。对加法而言,如果是浮点数和整型数据相加,就要先将整型转换为浮点型在进行加法运算,这就是典型的多态。

二、关于多态的实现

1.编译时的多态

编译过程中确定同名操作的对象。

2.运行时的多态

在程序运行过程中动态确定操作所指具体对象。

运算符重载

1.主要优点

改变现有运算符的操作方式,以用于类类型,使得程序看起来更直观。

2.重载规则

a.只能重载c++已有的运算符(除了少数几个外都可以重载)。 b.重载之后运算符的优先级和结合性不变。 c.一般来说,重载的功能与原有功能类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 d.规定:类属关系运算符".",成员指针运算符".*",作用域分辨符"::",三目运算符"?:"是不能重载的。 ### 3.重载的形式 #### 重载为类的非静态成员函数 ##### a.一般语法形式
返回类型 operator 运算符(形参表)
{
	函数体
}
b.形参表

函数的参数个数比原来的操作数个数少一个(后置"++","--"除外)。因为第一个操作数会被作为函数调用的目的对象,函数体中可以直接访问第一个操作数成员。

c.具体实现(以自增自减为例实现)
#include"pch.h"
#include<iostream>
using namespace std;
class Point//定义一个Point类
{
public:
	Point(int x,int y):x(x),y(y)
	{}
	//前置,单目运算所以没有形参
	//前置实现之后结果是左值,并且在实现的时候要实现数据共享,所以传引用
	 Point& operator++();
	 Point& operator--();

	 //后置,有一个int参数仅用于区分前置与后置
	 Point operator++(int);
	 Point operator--(int);
	void show()
	{
		cout << "the result is " << x <<";"<<y<< endl;
	}
private:
	int x,y;
};
//类的非静态函数成员实现
Point& Point::operator++()
{
	x++;
	y++;
	return *this;
}


Point& Point::operator--()
{
	x--;
	y--;
	return *this;
}

Point Point::operator++(int)
{
	Point old = *this;
	x++;
	y++;
	return old;
}

Point Point::operator--(int)
{
	Point old = *this;
	x--;
	y--;
	return old;
}
int main()
{
	Point po(6,7);
	po++.show();//6,7
	po--.show();//7,8
	po.show();//6,7
	(--po).show();//5,6	
	(++po).show();//6,7
	return 0;
}

重载为非成员函数

a.一般语法形式
返回类型 operator 运算符(形参表)
{
	函数体
}
b.关于访问权限

在实现运算符重载时,有时需要访问运算符参数所涉及类的私有成员,这时可以把该函数声明为类的友元函数。

c.形参表

参数个数与原操作数个数相同。

d.具体实现(以复数类为例实现)
#include"pch.h"
#include<iostream>
using namespace std;
class Complex
{
public:
	Complex(double real=0.0, double image=0.0) :real(real), image(image)
	{

	}
	//友元函数实现
	friend Complex& operator++(Complex &c1);
	friend Complex operator++(Complex &c1,int);
	void show()
	{
		cout << "(" << real << "," << image << ")" << endl;
	}
private:
	double real, image;
};
Complex& operator++(Complex &c1)
{
	c1.real++;
	c1.image++;
	return c1;
}
Complex operator++(Complex &c1, int)
{
	Complex c2 = c1;
	++(c1);
	return c2;
}
int main()
{
	Complex a(3.0, 4.0);
	Complex b(2.0, 5.0);
	(b++).show();//2,5
	b.show();//3,6
	(++a).show();//4,5
	return 0;
}

虚析构函数实现多态

关于它的实现

为了正确的调用对象的析构函数,一般要求具有层次结构的最原始的基类的析构函数定义为虚函数,因为在delete一个抽象类指针的时候,必须要通过虚函数才能找到真正的析构函数。

#include"pch.h"
#include<iostream>
using namespace std;
class Base
{
public:
	Base()
	{}
	virtual ~Base()//虚析构函数
	{
		cout << "destrutor of Base" << endl;
	}
};
class Derived :public Base
{
public:
	Derived()
	{}
	~Derived()
	{
		cout << "destrutor of Derived" << endl;
	}
};
int main()
{
	//先生成Base对象,然后生成Derived对象,返回派生类地址给基类指针
	Base *p = NULL;
	p = new Derived;
	delete p;
	return 0;
}

结果展示

如果基类析构函数不是虚函数,则不会动态绑定到派生类的析构函数。如果上述基类的析构函数不是虚函数,则有

纯虚函数以及抽象类

抽象类

关于抽象类

带有纯虚函数的类。它的主要作用是通过它为一个类族建立一个公有的接口,使它们能够更有效地发挥多态特性。

抽象类派生

如果派生类给出所有纯虚函数的实现,这个派生类就可以定义自己的对象,因而不再是抽象类;如果派生类并没有给出所有纯虚函数的实现,这时的派生类仍然是一个抽象类。

抽象类的特点

不能对其实例化。也就是说不能定义一个抽象类的对象,但是可以定义一个抽象类的指针和引用。

纯虚函数

声明格式

virtual 函数类型 函数名(参数表)=0;

注意点

如果将析构函数声明为纯虚函数,必须给出它的实现,因为派生类的析构函数体执行完后需要调用基类的纯虚函数。

posted on 2019-10-25 22:55  duoraemon  阅读(182)  评论(0编辑  收藏  举报