before|正文之前:
c++实验代码及学习笔记(四)
你好! 这是一个高程实验课的代码记录及学习笔记。我将记录一些重要的知识点、易错点。但是作为大学生,水平很低,敬请指点教导、优化代码。
1问题
首先我们来看一下问题
一提到面向对象,就不可避免提到类、封装、继承等等。但初学时总是云里雾里,大佬们欲说还休,也让类更加神秘。不难理解,在还没掌握基础语法的时候,去探究类与对象这些概念总是困难而不合时宜的。
学习类的基础操作是一件水到渠成的事。搞定了指针、数组、接口设计等等难啃的硬骨头,再接触类发现原来不过如此。没错,水到渠成就是如此简单。
然而教学鼓励我们在应用中掌握知识,老师基本讲解面向对象的四个特征:抽象、封装、继承、多态。我们或许能给出代码实例,照猫画虎地进行copy-create的循环。但是要说对类的理解,确实缺乏系统理论知识牢固基础,以及一些画龙点睛的点拨。
因此,在涉及具体原理时,我也欲说还休了——不是因为大佬,而是水平太菜。
闲言碎语少讲,进入正题吧
2思路
导入
我们说,面向对象的四个特征:
- 抽象
- 封装
- 继承
- 多态
……
这四个词就够抽象了好吗!!
不负责统计,99.9%的人,第一次见这些词都不知道什么含义。
没一点幽默风趣的比喻讲解,我这被惯坏的肤浅大脑根本理解不了。好吧,那就举个栗子?
抽象,就好比二狗博文里“问题”后的“思路”这一段。还不理解?来来来考考你,假说演绎法的几个步骤是什么?
观察分析、提出问题→推理想象,提出假说→演绎推理、预期实验结果→设计实验、验证预期
你说这跟计算机有什么关系?
都是解决问题,其中的逻辑是差不多的。当然,具体来说,抽象是计算机解决问题必要的一部分。我们做应用题,要分析问题、把它转变成计算机和数学的问题。比如这次对矩形操作,我们如何计算矩形大小?–长乘宽。二维矩形就用到了坐标轴,怎么表示?–坐标平面的坐标。然后再设计算法:用一个内联函数,输出一个结果。
这是我的理解,而有人会说,抽象就是把一个对象的分析出各个属性,来代替表达的手法。抽就是分离,象就是表示出来的部分。
比如说把一个学生对象抽象一下,就剩下他的一些属性和行为,例如姓名,性别,年龄,身高,学习的能力等等……
这也是一种理解。
那么我们说到类。
类是抽象的,而对象是具体的
官方一点,类是对象的模板。
我见到一个精妙绝伦的比喻(来源:谈谈我对面向对象以及类与对象的理解),《红色警戒》中美国大兵是一类兵种,点击制造后从兵营里出来的那个会开枪的家伙就是对象了:
这样理解就立马get了
而具体类的概念定义与应用,请参考理论书籍。
参考文章:【重点推荐】类和对象(一)——类&对象概念及定义
题目详解
那么回到本题,设计一个矩形类,表示边平行坐标轴那种方方正正的矩形。
- 求矩形面积
最直接的方法用坐标表示。几个坐标可以确定一个方方正正的矩形呢?
两个——左上角,右下角。四个值(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;
}
- 判断两个矩形是否相等
说到判断,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;
}
...
}
- 保持左上角坐标不变,改变矩形大小
想象画面:固定左上角,光标拖动矩形右下角,足以改变矩形成任意大小。
所以我们只需要“重设”右下角的数据即可。
- 保持大小不变,对矩形进行平移
方便的方法是新建一个向量,向量有vx,vy两个量,剩下的就是数学知识啦
void move(int vx, int vy)
{
x1 += vx;
x2 += vx;
y1 += vy;
y2 += vy;
}
- 判断两个矩形是否重叠
这道题呢有点东西,像我这么聪明的小脑瓜 ,当然没有想出来啦~于是有事问度娘,一题多解,果然有好方法
完整版参考 判断两个矩形相交以及求出相交的区域
矩形相交的情况:
判断矩形相交的方法呢,很多,有的很复杂
原博也给出了精彩的回答。既然我们要求相交的矩形,不如我们假设两个矩形相交,设相交之后的矩形为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最终效果
这次的题目还是相对简单呢,只是第一次写类难免会出很多小错误,还需要多多练习啊