功能:实现圆、椭圆、矩形、三角形、正多边形和任意多边形的管理,实现计算所有图形面积、长度,添加图形,删除图形,获取指定位置图形,输出图形信息等。
头文件1:stdafx.h 存放用到的头文件
#ifndef STDAFX_H_INCLUDED
#define STDAFX_H_INCLUDED
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#endif
头文件2:point2d.h 点类
#ifndef POINT2D_H_INCLUDED
#define POINT2D_H_INCLUDED
#include "stdafx.h"
//点类
class point2d {
public:
point2d() :m_x(0), m_y(0) {}
point2d(double x, double y) :m_x(x), m_y(y) {}
point2d(const point2d& p) {
m_x = p.m_x;
m_y = p.m_y;
}
void rewritex(double x) { m_x = x; }
void rewritey(double y) { m_y = y; }
double getx() { return m_x; }
double gety() { return m_y; }
private:
double m_x;
double m_y;
};
#endif
头文件3:shape.h 图形类
#ifndef SHAPE_H_INCLUDED
#define SHAPE_H_INCLUDED
#include "stdafx.h"
#include "point2d.h"
#define PI 3.1416926
//图形基类
class shape {
public:
virtual double calCirc() = 0;
virtual double calArea() = 0;
virtual void info() = 0;
virtual shape* expand() = 0;
};
//---------------------------圆类
class circle :public shape {
public:
circle() :m_r(1) {}
circle(double r) :m_r(r) {}
virtual double calCirc() {
return 2 * PI * m_r;
}
virtual double calArea() {
return PI * m_r * m_r;
}
virtual void info() {
cout << "圆" << " ";
cout << " 半径:" << m_r;
cout << " 周长:" << calCirc() << " 面积:" << calArea() << endl << endl;
}
virtual circle* expand() {
cout << "输入半径:";
float r = 0;
cin >> r;
circle* temp = new circle(r);
return temp;
}
private:
double m_r;
};
//---------------------------椭圆类
class oval :public shape {
public:
oval() :m_a(1), m_b(2) {}
oval(double a, double b) :m_a(max(a, b)), m_b(min(a, b)) {}
virtual double calCirc() {
return 2 * min(m_a, m_b) + 4 * (max(m_a, m_b) - min(m_a, m_b));
}
virtual double calArea() {
return PI * m_a * m_b;
}
void info() {
cout << "椭圆" << " ";
cout << "长轴半径:" << max(m_a, m_b) << " 短轴半径:" << min(m_a, m_b);
cout << " 周长:" << calCirc() << " 面积:" << calArea() << endl << endl;
}
virtual oval* expand() {
cout << "输入长轴、短轴:";
float a = 0, b = 0;
cin >> a >> b;
oval* temp = new oval(a, b);
return temp;
}
private:
double m_a;
double m_b;
};
//---------------------------矩形类
class rectangle :public shape {
public:
rectangle() :m_a(1), m_b(1) {}
rectangle(double a, double b) :m_a(max(a, b)), m_b(min(a, b)) {}
virtual double calCirc() {
return 4 * m_a * m_b;
}
virtual double calArea() {
return m_a * m_b;
}
virtual void info() {
cout << "矩形" << " ";
cout << "长:" << max(m_a, m_b) << " 宽:" << min(m_a, m_b);
cout << " 周长:" << calCirc() << " 面积:" << calArea() << endl << endl;
}
virtual rectangle* expand() {
cout << "输入长、宽:";
float a = 0, b = 0;
cin >> a >> b;
rectangle* temp = new rectangle(a, b);
return temp;
}
private:
double m_a;
double m_b;
};
//---------------------------三角形类
class triangle :public shape {
public:
triangle() :m_a(1), m_b(1), m_c(1) {}
triangle(double a, double b, double c) :m_a(a), m_b(b), m_c(c) {}
virtual double calCirc() {
return m_a + m_b + m_c;
}
virtual double calArea() {
return (double)1 / (double)4 * sqrt((m_a + m_b + m_c) * (m_a + m_b - m_c) * (m_a + m_c - m_b) * (m_b + m_c - m_a));
}
virtual void info() {
cout << "三角形" << " ";
cout << " 三边长:" << m_a << " " << m_b << " " << m_c;
cout << " 周长:" << calCirc() << " 面积:" << calArea() << endl << endl;
}
virtual triangle* expand() {
cout << "输入三边(自觉符合规范):";
float a = 0, b = 0, c = 0;
cin >> a >> b >> c;
triangle* temp = new triangle(a, b, c);
return temp;
}
private:
double m_a;
double m_b;
double m_c;
};
//---------------------------任意正多边形类
class regularShape :public shape {
public:
regularShape() :m_n(3), m_l(1) {}
regularShape(int n, double l) :m_n(n), m_l(l) {}
virtual double calCirc() {
return m_n * m_l;
}
virtual double calArea() {
return pow(calCirc(), 2) / ((tan(PI / m_n)) * (4 * (double)m_n));
}
virtual void info() {
cout << "正多边形" << " ";
cout << " 边数:" << m_n << " 边长:" << m_l;
cout << " 周长:" << calCirc() << " 面积:" << calArea() << endl << endl;
}
virtual regularShape* expand() {
cout << "输入边数、边长:";
float a = 0;
int b = 0;
cin >> a >> b;
regularShape* temp = new regularShape(b, a);
return temp;
}
private:
int m_n;
double m_l;
};
//---------------------------任意多边形类
class irregularShape :public shape {
public:
irregularShape() {
point2d p1(0, 0);
point2d p2(0, 1);
point2d p3(1, 1);
point2d p4(1, 0);
all_point2d.push_back(p1);
all_point2d.push_back(p2);
all_point2d.push_back(p3);
all_point2d.push_back(p4);
}
irregularShape(vector<point2d> point2d) :all_point2d(point2d) {}
~irregularShape() {}
virtual double calCirc() {
double Circ = 0;
for (unsigned int i = 0; i < all_point2d.size(); i++) {
if (i != all_point2d.size() - 1) { Circ += sqrt(pow((all_point2d[i].getx() - all_point2d[i + 1].getx()), 2) + pow((all_point2d[i].gety() - all_point2d[i + 1].gety()), 2)); }
else { Circ += sqrt(pow((all_point2d[i].getx() - all_point2d[0].getx()), 2) + pow((all_point2d[i].gety() - all_point2d[0].gety()), 2)); }
}
return Circ;
}
virtual double calArea() {
double Area = 0;
for (unsigned int i = 0; i < all_point2d.size(); i++) {
if (i != all_point2d.size() - 1) { Area += (all_point2d[i].getx() * all_point2d[i + 1].gety() - all_point2d[i + 1].getx() * all_point2d[i].gety()); }
else { Area += (all_point2d[i].getx() * all_point2d[0].gety() - all_point2d[0].getx() * all_point2d[i].gety()); }
}
return abs(Area) / 2;
}
virtual void info() {
cout << "任意多边形" << " " << "边数:" << all_point2d.size();
cout << " 周长:" << calCirc() << " 面积:" << calArea() << " 坐标:";
for (unsigned int i = 0; i < all_point2d.size(); i++) {
cout << " x" << i + 1 << "=" << all_point2d[i].getx() << " " << "y" << i + 1 << "=" << all_point2d[i].gety() ;
}
cout << endl << endl;
}
virtual irregularShape* expand() {
all_point2d.clear();
cout << "你想构造几边形?(>=3)";
int nums = 0;
do {
cin >> nums;
} while (nums < 3);
for (int i = 0; i < nums; i++) {
cout << "按顺时针输入第" << i + 1 << "个点的横、纵坐标,空格隔开:";
double x = 0, y = 0;
cin >> x >> y;
point2d p(x, y);
all_point2d.push_back(p);
}
irregularShape* temp = new irregularShape(all_point2d);
return temp;
}
public:
vector<point2d> all_point2d; //存放所有点
};
#endif // SHAPE_H_INCLUDED
头文件4:shapeManage.h 图形管理类
#ifndef SHAPEMANAGE_H_INCLUDED
#define SHAPEMANGE_H_INCLUDED
#include "stdafx.h"
#include "shape.h"
//图形管理类,实现计算所有图形面积、长度,添加图形,删除图形,获取指定位置图形,输出图形信息
class shapeManage {
public:
shapeManage() {
circle* circle1 = new circle();
oval* oval1 = new oval();
rectangle* rectangle1 = new rectangle();
triangle* triangle1 = new triangle();
regularShape* regularShape1 = new regularShape();
irregularShape* irregularShape1 = new irregularShape();
all_shapes.push_back(circle1);
all_shapes.push_back(oval1);
all_shapes.push_back(rectangle1);
all_shapes.push_back(triangle1);
all_shapes.push_back(regularShape1);
all_shapes.push_back(irregularShape1);
}
~shapeManage() {
for (unsigned int i = 0; i < all_shapes.size(); i++) {
if (all_shapes[i]) {
delete all_shapes[i];
all_shapes[i] = nullptr;
}
}
}
//计算所有图形总长度
void calAllCirm() {
double allCirc = 0;
for (unsigned int i = 0; i < all_shapes.size(); i++) {
allCirc += all_shapes[i]->calCirc();
}
cout << "所有图形总长度: " << allCirc << endl;
}
//计算所有图形总面积
void calAllArea() {
double allArea = 0;
for (unsigned int i = 0; i < all_shapes.size(); i++) {
allArea += all_shapes[i]->calArea();
}
cout << "所有图形总面积: " << allArea << endl;
}
//输出所有图形信息
void showAllInfo() {
cout << "当前图形个数:" << all_shapes.size() << endl;
calAllArea();
calAllCirm();
cout << endl <<"当前所有图形信息:" << endl << endl;
for (unsigned int i = 0; i < all_shapes.size(); i++) {
cout << " " << i + 1 << " : ";
all_shapes[i]->info();
}
}
//添加图形
void addShape() {
cout << endl << endl << "---->>>输入要添加的图形的序号:1.圆 2.椭圆 3.矩形 4.三角形 5.正多边形 6.任意多边形 ";
int n = 0, pos = 0;
cin >> n;
cout << endl << "输入要插入的位置(1~" << all_shapes.size() << "):";
cin >> pos;
int cnt = 1;
bool isInserted = false;
for (vector<shape*>::iterator it = all_shapes.begin(); cnt != all_shapes.size() + 1; it++) {
if (cnt == pos) {
switch (n) {
case 1: {circle* circle1 = new circle(); all_shapes.insert(it, (*circle1).expand()); delete circle1; circle1 = nullptr; isInserted = true; break; }
case 2: {oval* oval1 = new oval(); all_shapes.insert(it, (*oval1).expand()); delete oval1; oval1 = nullptr; isInserted = true; break; }
case 3: {rectangle* rectangle1 = new rectangle(); all_shapes.insert(it, (*rectangle1).expand()); delete rectangle1; rectangle1 = nullptr; isInserted = true; break; }
case 4: {triangle* triangle1 = new triangle(); all_shapes.insert(it, (*triangle1).expand()); delete triangle1; triangle1 = nullptr; isInserted = true; break; }
case 5: {regularShape* regularShape1 = new regularShape(); all_shapes.insert(it, (*regularShape1).expand()); delete regularShape1; regularShape1 = nullptr; isInserted = true; break; }
case 6: {irregularShape* irregularShape1 = new irregularShape(); all_shapes.insert(it, (*irregularShape1).expand()); delete irregularShape1; irregularShape1 = nullptr; isInserted = true; break; }
default:break;
}
}
cnt++; //遍历位置,使迭代器指向指定位置
if (isInserted) break; //若插入,则退出循环,防迭代器失效问题
}
}
//删除图形
void deleteShape() {
int pos = 0;
cout << endl << "输入要删除的位置(1~" << all_shapes.size() << "):";
cin >> pos;
vector<shape*>::iterator it = all_shapes.begin();
all_shapes.erase(it + pos - 1);
}
//获取指定位置图形
void getPos() {
cout << "输入图形序号:";
unsigned int pos = 1;
cin >> pos;
if (pos<1 || pos>all_shapes.size()) return;
cout << endl << "第" << pos << "个图形 : " << endl;
all_shapes[pos - 1]->info();
}
public:
vector<shape*> all_shapes; //存放所有图形
};
#endif // !SHAPEMANAGE_H_INCLUDED
cpp文件:main.cpp
#include "stdafx.h"
#include "shapeManage.h"
#include "shape.h"
void menu(shapeManage& shapes);
int main() {
shapeManage shapes; //初始化图形
shapes.showAllInfo(); //输出所有图形信息
menu(shapes);
system("pause");
return 0;
}
void menu(shapeManage& shapes) {
cout << endl << endl << "图形管理: 1.添加图形 2.删除图形 3.获取指定位置图形 ";
int m = 0;
do {
cin >> m;
} while (m <= 0 || m > 3);
switch (m) {
case 1: {shapes.addShape(); system("cls"); shapes.showAllInfo(); menu(shapes); break; }
case 2: {shapes.deleteShape(); system("cls"); shapes.showAllInfo(); menu(shapes); break; }
case 3: {shapes.getPos(); menu(shapes); break; }
default:exit(0);
}
}
运行结果:
需要注意的问题:
1.图形初始化,切不可直接创建对象,而是要动态开辟空间,
使用指针存放,原因是vector在堆上,如果直接创建对象存入vector,
在出作用域之后对象会被销毁,造成野指针的问题。
2.在vector插入新的对象时,在插入之后一定要跳出循环,
切不可继续进行下一次。原因是每当vector插入新对象,迭代器可能会失效。
改进之处:
1.在输入任意多边形的坐标时,必须按一定方向(顺时针或逆时针)输入,
否则会造成计算错误的问题,在以后可以进行改进,
使得无须按方向输入坐标也可以正确计算出面积和周长。
2.创建三角形对象时,并未分析用户输入是否合理
(两边之和大于第三边,两边之差小于第三边)。