【C++】继承访问权限测试、友元类继承测试与多态性的综合运用

87 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

【C++】继承访问权限测试、友元类继承测试与多态性的综合运用

一、实验目的与要求

继承访问权限测试、友元类继承测试与多态性的综合运用

二、实验结果

1.初始图形

image.png

2.移动与复制后的图形

image.png

三、实验分析与总结

通过在Dev C++平台中对图形类CShape的实现,对继承与多态的编码方式与访问权限有了更加深入的了解。同时,还熟悉了友元类的定义与编码实现,能够更加方便的对相关类进行处理。
在实验中,为了能够更好的实现对于各个图形的操作设置了共有继承类例如CShape,而其他一些类例如CPoint、CTriangle与CRect通过public、protect与private这些方式继承了CShape。使得CPoint等这些派生类可以从基类CShape中获得其自身不曾定义过的成员,并且这让CPoint等类与基类CShape中的成员具有相同的属性,提高了我们的编程效率。
在实验过程中我们还使用了函数的重载,例如在CTriangle中将基类的GetArea与Draw等方法进行了重载,这样达到了一名多用的效果,让项目中相同作用的方法明朗直接的显示在我们眼前,使得所编写项目中的代码更加容易被理解。
在多态性方面,在实验中对输入输出完全一样的一般性多态函数做出了定义,例如virtual double GetArea();对于其他例如析构函数也做出了多态性说明,例如:virtual ~CShape()。
对于友元类,私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口间接地进行。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦。因此我们设置了友元类,能够在类的成员函数外部直接访问对象的私有成员,很好的解决了编码麻烦的问题,同时也能够很好的对数据做出保护。
通过此次实验,对C++的相关知识有了更为深入的了解。通过在DevC++软件上的实验操作掌握了继承访问权限测试、友元类继承测试与多态性的综合运用与原理,为后续软件编程的学习打下了基础。

四、关键源代码

#include "graphics.h"
#include<iostream>
#include "CShape.h"
#include<vector>
using namespace std;

int main()
{
	// 图形画布基础设置
	initgraph(640, 480, INIT_RENDERMANUAL);//初始化显示一个窗口 
	setbkcolor(WHITE);                     //窗口背景颜色                          
	setcolor(BLACK);                       //图形边框色 
	setfont(20, 0, "楷体");
	setbkmode(TRANSPARENT);                //绘图背景透明 

	vector<CShape*>shapes;
	vector<CShape*>shapestmp;

	shapes.push_back(new CTriangle(CPoint(450, 100), CPoint(400, 200), CPoint(500, 200))); //使用push.back尾部加入数据 
//	shapes.push_back(new CTriangle(CPoint(10, 10), CPoint(150, 10), CPoint(150, 150)));
	shapes.push_back(new CRect(CPoint(250, 100), CPoint(350, 200)));
	shapes.push_back(new CRecTri(CRect(CPoint(100, 100), CPoint(200, 200))));

	

	//移动
	bool move_flag = false;
	bool copy_flag = false;
	bool redraw = true;
	//鼠标点击时记录它的坐标
	int clickX, clickY;
	int copyX, copyY;
	int checkedid = -1;
	int copyid = -1;
	
	for (; is_run(); delay_fps(60)) { //循环,is_run判断窗口是否还在,delay_fps是延时
		while (mousemsg()) {          //获取鼠标消息,这个函数会等待,等待到有消息为止
			mouse_msg msg = getmouse();  

			//判断鼠标的移动
			if (msg.is_move()) {
				if (checkedid != -1) {
					if (move_flag) {
						shapes[checkedid]->Move(msg.x - clickX, msg.y - clickY);
					}
				}
				clickX = msg.x;
				clickY = msg.y; 
				redraw = true;
			}

			// 判断鼠标左键
			else if (msg.is_left()) {
				// 判断鼠标左键是否按下
				if (msg.is_down()) {
					clickX = msg.x;
					clickY = msg.y;

					CPoint pt = CPoint(clickX, clickY);
					int isIn = 0;
					for (int i = 0; i < shapes.size(); i++) {
						if (shapes[i]->ptIn(pt)) {
							isIn = 1;
							//如果鼠标在图形区域内就设置移动的flag为true
							move_flag = true;
							checkedid = i;
							redraw = true;
							break;
						}
					}
					if (isIn == 0)
						checkedid = -1;
				}
				else {
					move_flag = false;
				}
			}
		}
		// 重新绘图
		if (redraw) {
			redraw = false;
			cleardevice();
			for (int i = 0; i < shapes.size(); i++) {
				if (i == checkedid)
					shapes[i]->DrawBlue();
				else
					shapes[i]->Draw();
			}
		}

		while (kbmsg()) {
			key_msg msgk = getkey();
			if (msgk.key == key_A && msgk.msg == key_msg_down) {
				mouse_msg msgm = getmouse();
				if (msgm.is_left()) {
					// 判断鼠标左键是否按下	
					if (msgm.is_down()) {
						shapes.push_back(new CRect(CPoint(msgm.x, msgm.y)));
						redraw=true;
					}
				}
				if (msgm.is_right()) {
					// 判断鼠标右键是否按下
					if (msgm.is_down()) {
						shapes.push_back(new CTriangle(CPoint(msgm.x, msgm.y)));
						redraw=true;
					}
				}
			}
			if (msgk.key == key_Z && msgk.msg == key_msg_down) {
				mouse_msg msgm = getmouse();
				if (msgm.is_left()) {
					// 判断鼠标左键是否按下
					if (msgm.is_down()) {
						copyX = msgm.x;
						copyY = msgm.y;

						CPoint pt = CPoint(copyX, copyY);
						for (int i = 0; i < shapes.size(); i++) {
							if (shapes[i]->ptIn(pt)) {
								//如果鼠标在图形区域内就设置移动的flag为true
								copy_flag = true;
								copyid = i;
								break;
							}
						}
					}
				}
				if (msgm.is_right()) {
					// 判断鼠标右键是否按下
					if (msgm.is_down()) {
						if (copy_flag == true) {
							shapes.push_back(&(shapes[copyid]->Clone())->Move(msgm.x-copyX,msgm.y-copyY));
							redraw = true;
						}
					}
				}
			}
		}
	}
	closegraph();
	return 0;
}