多态与重载

多态和重载

一:多态

1:定义:多态是指同样的消息被不同类型的对象接收时导致的不同行为。

消息是指对类的成员函数的调用。不同行为是指不同的实现,即调用了不同的函数。

2:多态的类型:
1:专用多态 :

​ 1:重载多态

​ 2:强制多态

2:通用多态:

​ 3:包含多态

​ 4:参数多态

3:多态的实现:编译时的多态和运行时的多态

两者分别在编译过程中和运行过程中进行确定操作对象。

这种确定操作的具体对象又被称为绑定,即将一个的方法和一条消息进行结合的过程。

静态绑定:绑定工作在编译连接阶段完成的情况.eg:重载,强制和参数多态就通过静态绑定实现。

动态绑定:在程序运行阶段完成。

二:重载

接下来我们介绍运算符重载

1:定义:运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。
实质:函数重载。

您可以重定义或重载大部分 C++ 内置的运算符。

(注意:1:有些运算符是不能进行重载的,eg:三目运算符“?:”,作用域分辨符“::”而且只能重载C++中已经有的运算符

​ 2:运算符的优先级和结合性不会变)

这样,您就能使用自定义类型的运算符。

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

Box operator+(const Box&);
2:运算符重载为成员函数和非成员函数

注意:当重载为类的成员函数时,函数的参数个数要比原来的操作数个数要少一个(后置“++”,“——”除外),重载为非成员函数时,操作个数相同。

a:重载为非成员函数

eg:双目运算符重载为成员函数

#include<iostream>

using namespace std;
class complex
{
public:
	complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}
	complex operator+(const complex& c2) const;//运算符+重载成员函数
	complex operator-(const complex& c2) const;//运算符-重载成员函数
	void display() const;
private:
	double real;
	double imag;
};
complex complex::operator+(const complex& c2) const
{
	return complex(real + c2.real, imag + c2.imag);//创建一个临时无名对象作为返回值
}
complex complex::operator-(const complex& c2) const
{
	return complex(real - c2.real, imag - c2.imag);
}
void complex::display() const
{
	cout << "(" << real << "," << imag << ")" << endl;
}
int main()
{
	complex c1(5, 4), c2(2, 10), c3;
	cout << "c1="; c1.display();
	cout << "c2="; c2.display();
	c3 = c1 - c2;//使用重载运算符完成复数减法
	cout << "c3=c1-c2="; c3.display();
	c3 = c1 + c2;
	cout << "c3=c1+c2="; c3.display();
	return 0;
}

1572153726072

单目运算符重载为成员函数

eg:

#include<iostream>
using namespace std;
class clock
{
public:
	clock(int hour = 0, int minute = 0, int second = 0);
	void showtime() const;
	clock& operator++();
	clock operator++(int);
private:
	int hour, minute, second;
};
clock::clock(int hour, int minute, int second)
{
	if (0 <= hour && hour < 24 && 0 <= minute && minute < 60 && 0 <= second && second < 60)
	{
		this->hour = hour;
		this->minute = minute;
		this->second = second;
	}
	else
	{
		cout << "time error!" << endl;
	}
}
void clock::showtime() const
{
	cout << hour << ":" << minute << ":" << second << endl;
}
clock& clock::operator++()//前置单目运算符重载函数
{
	second++;
	if (second >= 60)
	{
		second -= 60;
		minute++;
		if (minute >= 60)
		{
			minute -= 60;
			hour = (hour + 1) % 24;
		}
	}
	return *this;
}
clock clock::operator++(int)//后置单目运算符重载
{
	clock old = *this;
	++(*this);//调用前置“++”运算符
	return old;
}
int main()
{
	clock myclock(23, 59, 59);
	cout << "first time output: ";
	myclock.showtime();
	cout << "show myclock++   ";
	(myclock++).showtime();
	cout << "show ++myclock   ";
	(++myclock).showtime();
	return 0;
}

1572153919709

注意:语法规定,前置单目重载为运算符时没有形参,而后置单目需要有一个int型的形参。
b:重载为非成员函数

注意:1:这时运算所需要的操作数都需要通过函数的形参表来传递。

2:若需要访问运算符参数对象的私有成员,可以将该函数声明我友元函数。

函数的使用方法:

重载双目运算符U: oprd1 U oprd2 = operator U (opad1,oprd2)

前置单目运算符U:Uoprd = operator U(oprd)

后置单目运算符U:oprd U = operator U(oprd, 0)
eg:

Complex operator -(Complex C1, Complex C2) 

{
Complex Temp;
Temp.Vector_x= C1.getVector_x()- C2.getVector_x();
Temp.Vector_y = C1.getVector_y() - C2.getVector_y();
return Temp;
}

总结:

重载简单来说重载为成语函数会更接简单一些,但有些情况需要使用重载为非成员函数。

eg:

1:要重载的操作符的第一个操作数不是可以更改的类型。

2:以非成员函数的形式重载,支持更灵活的形式转变。

posted @ 2019-10-27 14:14  木有兮  阅读(717)  评论(0编辑  收藏  举报