c/c++ 类与对象 矩形计算实例

before|正文之前:

c++实验代码及学习笔记(四)

你好! 这是一个高程实验课的代码记录及学习笔记。我将记录一些重要的知识点、易错点。但是作为大学生,水平很低,敬请指点教导、优化代码。

1问题

首先我们来看一下问题
问题描述
一提到面向对象,就不可避免提到类、封装、继承等等。但初学时总是云里雾里,大佬们欲说还休,也让类更加神秘。不难理解,在还没掌握基础语法的时候,去探究类与对象这些概念总是困难而不合时宜的。
学习类的基础操作是一件水到渠成的事。搞定了指针、数组、接口设计等等难啃的硬骨头,再接触类发现原来不过如此。没错,水到渠成就是如此简单。
然而教学鼓励我们在应用中掌握知识,老师基本讲解面向对象的四个特征:抽象、封装、继承、多态。我们或许能给出代码实例,照猫画虎地进行copy-create的循环。但是要说对类的理解,确实缺乏系统理论知识牢固基础,以及一些画龙点睛的点拨。
因此,在涉及具体原理时,我也欲说还休了——不是因为大佬,而是水平太菜。

闲言碎语少讲,进入正题吧


2思路

导入

我们说,面向对象的四个特征:

  • 抽象
  • 封装
  • 继承
  • 多态

……
这四个词就够抽象了好吗!!
不负责统计,99.9%的人,第一次见这些词都不知道什么含义。
没一点幽默风趣的比喻讲解,我这被惯坏的肤浅大脑根本理解不了。好吧,那就举个栗子?
抽象,就好比二狗博文里“问题”后的“思路”这一段。还不理解?来来来考考你,假说演绎法的几个步骤是什么?

观察分析、提出问题→推理想象,提出假说→演绎推理、预期实验结果→设计实验、验证预期

你说这跟计算机有什么关系?
计算机基础
都是解决问题,其中的逻辑是差不多的。当然,具体来说,抽象是计算机解决问题必要的一部分。我们做应用题,要分析问题、把它转变成计算机和数学的问题。比如这次对矩形操作,我们如何计算矩形大小?–长乘宽。二维矩形就用到了坐标轴,怎么表示?–坐标平面的坐标。然后再设计算法:用一个内联函数,输出一个结果。
这是我的理解,而有人会说,抽象就是把一个对象的分析出各个属性,来代替表达的手法。抽就是分离,象就是表示出来的部分。
比如说把一个学生对象抽象一下,就剩下他的一些属性和行为,例如姓名,性别,年龄,身高,学习的能力等等……
这也是一种理解。

那么我们说到类。

类是抽象的,而对象是具体的

官方一点,类是对象的模板。
我见到一个精妙绝伦的比喻(来源:谈谈我对面向对象以及类与对象的理解),《红色警戒》中美国大兵是一类兵种,点击制造后从兵营里出来的那个会开枪的家伙就是对象了:
参考
这样理解就立马get了
而具体类的概念定义与应用,请参考理论书籍。
参考文章:【重点推荐】类和对象(一)——类&对象概念及定义

题目详解

那么回到本题,设计一个矩形类,表示边平行坐标轴那种方方正正的矩形。

  1. 求矩形面积

最直接的方法用坐标表示。几个坐标可以确定一个方方正正的矩形呢?
两个——左上角,右下角。四个值(x1,y1) (x2,y2)
然后边长*边长即可

我们创建一个rectangle类
定义私有数据

class rectangle
{
private:
	int x1, y1, x2, y2;//A(x1,y1),B(x2,y1),C(x2,y2),D(x1,y2)
}

类中写一个void函数用来设定坐标;
一个整型函数求面积
注意,成员函数可直接访问成员变量

public:                                                       
	void set(int x1, int y1, int x2, int y2)
	{
		this->x1 = x1;
		this->x2 = x2;
		this->y1 = y1;
		this->y2 = y2;
	}

	int area()
	{
		int s;
		s = (x1 - x2)*(y1 - y2);
		if (s < 0)
		{
			s = -s;
		}
		return s;
	};

在主函数中,我们该如何调用呢?
简单来说,就是用类(模板)创造一个对象
这里我们创建一个矩形c。c具有矩形类的所有属性。
然后我们用c.set、c.area调用函数
问题即可解决

int main()
{
	rectangle c;
	int x1, x2, y1, y2;
	
	cout << "输入矩形左上角右下角坐标: 左上角(x1,y1)" << endl;
	cin >> x1 >> y1;
	cout << "右下角(x2,y2)" << endl;
	cin >> x2 >> y2;
	
	c.set(x1, y1, x2, y2);

	//求矩形面积
	cout << "矩形面积是:" << c.area() << endl;
	return 0;
}
  1. 判断两个矩形是否相等

说到判断,c++中最常用的是bool函数。在这里,判断两个矩形相等,我想应该是数学意义上的全等,长=长,宽=宽,边长相等。有一个边不相等即false
新建一个矩形类d,作为参数传入函数与原配比较

bool equal(rectangle d)
	{
		if ((d.x1-d.x2)!=(this->x1-this->x2)||
			(d.y1-d.y2)!=(this->y1-this->y2))
			return false;
		return true;
	};
int main
{
	...
	if (c.equal(d)==true)
	{
		cout << "两个矩形相等" << endl;
	}
	else {
		cout << "两个矩形不等" << endl;
	}
	...
}
  1. 保持左上角坐标不变,改变矩形大小

想象画面:固定左上角,光标拖动矩形右下角,足以改变矩形成任意大小。
所以我们只需要“重设”右下角的数据即可。

  1. 保持大小不变,对矩形进行平移

方便的方法是新建一个向量,向量有vx,vy两个量,剩下的就是数学知识啦

void move(int vx, int vy)
	{
		x1 += vx;
		x2 += vx;
		y1 += vy;
		y2 += vy;
	}
  1. 判断两个矩形是否重叠

这道题呢有点东西,像我这么聪明的小脑瓜 ,当然没有想出来啦~于是有事问度娘,一题多解,果然有好方法
完整版参考 判断两个矩形相交以及求出相交的区域
矩形相交的情况:
在这里插入图片描述
判断矩形相交的方法呢,很多,有的很复杂
原博也给出了精彩的回答。既然我们要求相交的矩形,不如我们假设两个矩形相交,设相交之后的矩形为C,且矩形C的左上角坐标为(Xc1,Yc1),右下角坐标为(Xc2,Yc2)
很显然可以得到:
Xc1 = max(Xa1,Xb1)
Yc1 = max(Ya1,Yb1)
Xc2 = min(Xa2,Xb2)
Yc2 = min(Ya2,Yb2)
这样就求出了矩形的相交区域。

Xc1,Yc1,Xc2,Yc2只要同时满足下面两个式子,就可以说明两个矩形相交。
Xc1 <= Xc2
Yc1 <= Yc2

假设-验证
是不是十分简单呢~
转换思路,我们直接创建一个新的矩形类,用两矩形相交来为这个新矩形赋值。
值得注意的是max和min函数不在iostream库中,我们需要包含一个#algorithm库

void coincide(rectangle c, rectangle d)
	{
		x1 = max(c.x1, d.x1);
		y1 = max(c.y1, d.y1);
		x2 = min(c.x2, d.x2);
		y2 = min(c.y2, d.y2);
		if ((x1 <= x2) && (y1 <= y2))
			cout << "两矩形重叠" << endl;
		else {
			cout << "两矩形不重叠" << endl;
		}
	}

为方便起见,我写了一个打印函数,每次生成新的矩形都可以打印一遍位置。

3代码实现

#include <iostream>
#include <algorithm>
using namespace std;

class rectangle
{
private:
	int x1, y1, x2, y2;//A(x1,y1),B(x2,y1),C(x2,y2),D(x1,y2)

public:                                                       
	void set(int x1, int y1, int x2, int y2)
	{
		this->x1 = x1;
		this->x2 = x2;
		this->y1 = y1;
		this->y2 = y2;
	}

	int area()
	{
		int s;
		s = (x1 - x2)*(y1 - y2);
		if (s < 0)
		{
			s = -s;
		}
		return s;
	};

	bool equal(rectangle d)
	{
		if ((d.x1-d.x2)!=(this->x1-this->x2)||
			(d.y1-d.y2)!=(this->y1-this->y2))
			return false;
		return true;
	};

	void setright(int x2,int y2)
	{
		this->x2 = x2;
		this->y2 = y2;
	}

	void move(int vx, int vy)
	{
		x1 += vx;
		x2 += vx;
		y1 += vy;
		y2 += vy;
	}

	void coincide(rectangle c, rectangle d)
	{
		x1 = max(c.x1, d.x1);
		y1 = max(c.y1, d.y1);
		x2 = min(c.x2, d.x2);
		y2 = min(c.y2, d.y2);
		if ((x1 <= x2) && (y1 <= y2))
			cout << "两矩形重叠" << endl;
		else {
			cout << "两矩形不重叠" << endl;
		}
	}

	void print()
	{
		cout << "目前矩形的坐标" << endl;
		cout << "(" << x1 << "," << y1 <<")" << endl;
		cout << "(" << x2 << "," << y2 << ")" << endl;

	}

};


void scanf(int &x1, int &y1, int &x2, int &y2)
{
	cout << "输入矩形左上角右下角坐标: 左上角(x1,y1)" << endl;
	cin >> x1 >> y1;
	cout << "右下角(x2,y2)" << endl;
	cin >> x2 >> y2;

}

int main()
{
	rectangle c;
	rectangle d;
	rectangle e;
	int x1, x2, y1, y2;
	int x3, y3, x4, y4;
	scanf(x1, y1, x2, y2);
	scanf(x3, y3, x4, y4);

	c.set(x1, y1, x2, y2);
	d.set(x3, y3, x4, y4);

	//求矩形面积
	cout << "矩形面积是:" << c.area() << endl;

	//判断矩形大小相等
	if (c.equal(d)==true)
	{
		cout << "两个矩形相等" << endl;
	}
	else {
		cout << "两个矩形不等" << endl;
	}

	//重设矩形大小
	int x2new, y2new;
	cout << "请输入新的右下角坐标:" << endl;
	cin >> x2new >> y2new;
	c.setright(x2new,y2new);
	c.print();

	//移动矩形
	int vx, vy;
	cout << "请输入位移向量:" << endl;
	cin >> vx >> vy;
	c.move(vx, vy);
	c.print();

	//求两矩形重叠区域
	e.coincide(c,d);
	e.print();

	getchar();
	getchar();
	return 0;
}

4最终效果

最终效果:
这次的题目还是相对简单呢,只是第一次写类难免会出很多小错误,还需要多多练习啊

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值