第五次作业--运算符重载与虚函数

运算符重载和虚函数

运算符重载

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

  • 规则:

    (1)C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已经有的运算符(不能重载的运算符:成员访问符 "." 、成员指针运算符". *" 、作用域分辨符"::" 、三目运算符"?😊

    (2)重载之后运算符的优先级和结合性不会改变

    (3)运算符的重载是由于对新的数据类型有需求,所以对原有运算符进行改造,所以重载功能应与原有功能相似,不能改变原有运算符的操作对象个数,同时至少要有一个操作对象是自定义类型

  • 语法:

  • 注意:

(1)当以非成员函数进行重载时,有时需要访问运算符所涉及的私有成员,这是可以把该函数声明为类的友元函数

(2)当运算符重载为类的成员函数时,函数参数个数要比原来的参数少一个(后置"++" "--"除外);为非成员函数时,参数与原有的相同

(3)前置“++” “--”和后置“++” “--”:成员函数形参:没有形参;非成员函数:重载函数有一个int类型

  • 程序

以双目运算符重载,实现Counter类的相加和整数与类相加(成员函数)、相减(非成员函数)

#include<iostream>
#include<Windows.h>

using namespace std;

class Counter;
class Counter
{
public:
	Counter(int data=0) :data(data) {};
	Counter operator +(Counter &p);//一个参数,另外一个参数为this所指的对象
	Counter operator +(int);
	friend Counter operator -(Counter &p, const int a);//两个参数,保持不变
	inline void Show() const;
private:
	int data;
};

//类与类相加,Counter 自定义类型
Counter Counter::operator+(Counter &p)
{
	data = data + p.data;
	return (*this);
}
Counter Counter::operator+(int a)
{
	data = data + a;
	return (*this);
}
void Counter::Show() const
{
	cout<< data << endl;
}
Counter operator - (Counter &p, const int a)
{
	Counter pt;
	pt.data = p.data - a;
	return a;
}

int main()
{
	Counter c1(5);
	Counter c2;
	Counter c3;

	cout << "The Origin Of c1:";
	c1.Show();

	cout << "The Origin Of c2:";
	c2.Show();

	c1 + 5;
	cout << "c1=c1+5=";
	c1.Show();

	c3=c1 - 5;
	cout << "c1-5=";
	c3.Show();

	c2 + c1;
	cout << "c2=c2+c1=";
	c2.Show();

	system("pause");
	return 0;
}

运行结果

单目运算符重载,实现Point类的前置"++"、后置"++"、前置"--"、后置"--",运用引用,节省内存,不用再创建一个对象,进行保存

#include<iostream>
#include<Windows.h>

using namespace std;

class Point
{
public:
	Point(double x = 0, double y = 0) :x(x), y(y) {};
	Point & operator ++();
	Point &operator ++( const int);
	Point & operator --();
	Point &operator --(const int);
	inline void Show() const;
private:
	double x, y;
};
//功能:实现前置++
Point &Point::operator++()
{
	++x;
	++y;
	return *this;
}

//功能:实现后置++
Point& Point::operator++(const int)
{
	Point old(*this);
	++(*this);
	return old;
}

//功能:实现前置--
Point & Point::operator--()//引用用于返回一个地址,就不用在多创建对象,消耗内存
{
	--x;
	--y;
	return *this;
}

//功能:实现后置--
Point &Point::operator--(const int)
{
	Point old = (*this);
	--(*this);
	return old;
}

//功能:显示点的坐标
inline void Point::Show() const
{
	cout << "(" << x << "," << y << ")" << endl;
}
int main()
{
	//测试前置++和后置--
	Point p1(3, 4);
	Point p2;

	cout << "The Origin Of P1 :";
	p1.Show();

	//p1前置++
	++p1;
	cout << "++P1 =";
	p1.Show();

	//p1后置++
	p2 = p1++;
	cout << "P2=P1++ =";
	p2.Show();
	cout << "P1++ =";
	p1.Show();

	//测试前置--和后置--
	Point p3(8, 9);
	Point p4;

	cout << "The Origin Of P3 :";
	p3.Show();

	//p3前置++
	--p3;
	cout << "--P3 =";
	p3.Show();

	//p3后置--
	p4 = p3--;
	cout << "P4=P3-- =";
	p4.Show();
	cout << "P3-- =";
	p3.Show();

	system("pause");
	return 0;
}

运行结果

虚函数和抽象类

虚函数可以用于实现多态,而多态的条件有3:(1)满足兼容规则(2)要声明虚函数(3)成员函数的调用通过指针、引用访问

  • 一般虚函数

    (1)语法:virtual 函数类型 函数名(形参表)

    (2)注意:函数声明只能在类的定义中的函数原型声明中,不能在成员函数实现时

    (3)虚函数一般不声明成内联函数,因为对虚函数调用是需要动态绑定,而内联函数的处理为静态,所以一般不将虚函数声明成内联函数

  • 纯虚函数

    (1)语法:virtual 函数类型 函数名(形参表)=0

    (2)定义为纯虚函数后在基类可以不给出函数的实现部分,由派生类给出不同的函数实现,从而实现多态

  • 抽象类

    (1)具有纯虚函数的类叫抽象类

(2)抽象类不能实例化,即不能生成对象

  • 程序

    以Shape(抽象类)作为基类,派生出_Rectangle和Circle类,使用指针进行对象的访问

头文件定义

class Shape//抽象类Shape
{
public:
	virtual double getArea() const=0;
	virtual double getPerim() const=0;
};

class _Rectangle :public Shape
{
public:
	_Rectangle(float length, float width) :length(length), width(width) {};
	double getArea() const;
	double getPerim() const;
	inline void Show() const;
private:
	float length;
	float width;
};

class Circle :public Shape
{
public:
	Circle(float Radius) :Radius(Radius) {};
	double getArea() const;
	double getPerim() const;
	inline void Show() const;
private:
	double Radius;
};

头文件实现和main函数实现

#include<iostream>
#include<Windows.h>
#include<cstdlib>
#include"8-6.h"

constexpr auto PI  = 3.1415926;

using namespace std;

double _Rectangle::getArea() const
{
	return (length * width);
}

double _Rectangle::getPerim() const
{
	return (2 * length + 2 * width);
}

inline void _Rectangle::Show() const
{
	cout << "The Area Of Rectangle :" << getArea() << endl;
	cout << "The Perim Of Rectangle :" << getPerim() << endl;
}

double Circle::getArea() const
{
	return (Radius *Radius *PI);
}
double Circle::getPerim() const
{
	return (2 * Radius*PI);
}
inline void Circle::Show() const
{
	cout << "The Area Of Circle : " << getArea() << endl;
	cout << "The Perim Of Circle : " << getPerim() << endl;
}
void fun(Shape *ptr)
{
	ptr->getArea();
	ptr->getPerim();
}
int main()
{
	//测试:Shape不能实例化
	//Shape p;

	_Rectangle s(3, 4);

	//通过对象操作
	/*s.getArea();
	s.getPerim();*/

	//通过指针操作,运用虚函数,使指针指向对所引用的对象
	fun(&s);
	s.Show();

	Circle c(3);

	/*c.getArea();
	c.getPerim();*/

	fun(&c);
	c.Show();
	system("pause");
	return 0;
}

运行结果

posted @ 2019-10-27 22:01  依言  Views(457)  Comments(0Edit  收藏  举报