矢量图管理系统
摘要
利用面向对象的封装性、继承性和多态性等技术设计了该矢量图管理系统,可以创建多种矢量图,用智能指针来进行管理矢量图对象的内存申请与释放,并用STL<vector>容器进行矢量图对象的储存。程序界面设计采用了EGE图形库,监听鼠标与键盘消息来实现不同的矢量图图形操作(如选中、拖动、新建、复制、粘贴等),以及实现了使用文件流从TXT文件读取数据来绘制矢量图图形,并可以再次保存至TXT文件。
1. 总体设计
系统功能:
- 设置画布绘制矢量图图形
- 选择TXT文件读取矢量图数据
- 将矢量图数据保存至TXT文件
- 智能指针对矢量图对象进行新建、删除的内存管理
- 矢量图操作:
- 新建矢量图图形(共5种矢量图可创建)
- 选中、拖动矢量图图形
- 复制、粘贴矢量图图形
- 删除、撤销最近一次新建矢量图图形
类图:
类方法:
double GetArea() const; // 计算机矢量图面积
bool ptIn(const CPoint& pt) const; // 判断参数坐标是否在矢量图形内
bool InRect(const CRect& rc) const; // 判断该图形是否在这个矩形内,用来判断矢量图是否有重叠部分
void Draw() const; // 在画板上绘制矢量图,但不填充颜色
void DrawColor(); // 在画板上绘制矢量图,并填充相应颜色
int id() const; // 返回当前矢量图的类型
CShape* Clone() const; // 复制矢量图
CShape& Move(int nOffsetX, int nOffsetY); // 对矢量图坐标进行移动
其他方法:
// 初始化
void init();
// 绘图
void reDraw(vector<AutoPtr<CShape>> shps, int checkedid);
// 字符串转换
char* wcharTochar(const wchar_t* _wchar);
// 选择文件
bool openFileDialog(string& filePath, bool rw);
// 读取文件
void readFile(vector<AutoPtr<CShape>>& shps, vector<AutoPtr<CPoint>>& points, string filePath);
// 保存文件
void saveFile(string filePath, vector<AutoPtr<CShape>> shps, vector<AutoPtr<CPoint>> points);
// 判断鼠标操作:选择、拖动矢量图形
void judgeMousemsg(mouse_msg msg, vector<AutoPtr<CShape>>& shps, vector<AutoPtr<CPoint>>& points, int& checkedid, bool& move_flag, int& clickX, int& clickY, bool& redraw);
// 判断键盘操作:新建矢量图形,复制、粘贴矢量图,删除、撤销最近一次新建矢量图形,清屏,打开文件,保存文件,更改窗口大小
void judgeKbmsg(key_msg msgk, vector<AutoPtr<CShape>>& shps, vector<AutoPtr<CPoint>>& points, int& checkedid, int&x, int &y, bool& copy_flag, int& copyid, int& copyX, int& copyY, bool& full, string& filePath);
2. 代码实现
**智能指针:**用来进行对矢量图对象的新建与删除的内存管理
template <class T>
class AutoPtr
{
public:
//构造函数
AutoPtr(T* pData);
//拷贝构造函数
AutoPtr(const AutoPtr<T>& h);
//声明周期结束时调用析构函数
~AutoPtr();
//等号的重载
AutoPtr<T>& operator=(const AutoPtr<T>& h);
//用户数减1
void decrUser();
//指针运算符重载(返回的指针允许被改变)
T* operator ->()
{
return m_pData;
}
//返回一个对象(能使用成员运算符(".")来访问成员变量)
T& operator*()
{
return *m_pData;
}
const T& operator *() const
{
return *m_pData;
}
//指针运算符重载(返回的指针不允许被改变)
const T* operator -> () const
{
return m_pData;
}
private:
//存储数据
T* m_pData;
//存储用户数
int* m_nUser;
};
template < class T>
AutoPtr<T>::AutoPtr(T* pData)
{
m_pData = pData;
//初始化用户数为1
m_nUser = new int(1);
}
template < class T>
AutoPtr<T>::AutoPtr(const AutoPtr<T>& h)
{
m_pData = h.m_pData;
m_nUser = h.m_nUser;
//用户数加1
(*m_nUser)++;
}
template < class T>
AutoPtr<T>& AutoPtr<T>::operator=(const AutoPtr<T>& h)
{
decrUser();
m_pData = h.m_pData;
m_nUser = h.m_nUser;
(*m_nUser)++;
return *this;
}
template < class T>
void AutoPtr<T>::decrUser()
{
--(*m_nUser);
if ((*m_nUser) == 0)
{
//删除数据
delete m_pData;
//地址赋为空
m_pData = 0;
delete m_nUser;
m_nUser = 0;
}
}
template < class T>
AutoPtr<T>::~AutoPtr()
{
decrUser();
}
各个矢量图类
#include "CShape.h"
#include "graphics.h"
#include <iostream>
using namespace std;
//CShape
CShape::CShape(){
}
CShape::CShape(const CShape& shape) {
m_sName = shape.m_sName;
}
CShape::~CShape(){
}
double CShape::GetArea() const {
return 0;
}
bool CShape::ptIn(const CPoint& pt) const {
return false;
}
bool CShape::InRect(const CRect& rc) const {
return false;
}
void CShape::Draw() const{
}
void CShape::DrawColor(){
}
CShape* CShape::Clone() const {
return new CShape(*this);
}
CShape& CShape::Move(int nOffsetX, int nOffsetY) {
return *this;
}
int CShape::id() const {
return 0;
}
//CPoint
CPoint::CPoint(int nPosX, int nPosY) {
m_nPosX = nPosX;
m_nPosY = nPosY;
}
CPoint::CPoint(const CPoint& pt) {
m_nPosX = pt.m_nPosX;
m_nPosY = pt.m_nPosY;
}
CPoint::~CPoint() {
//cout << "CPoint::~CPoint()\n";
}
double CPoint::GetArea() const {
return 0;
}
bool CPoint::ptIn(const CPoint& pt) const {
return false;
}
bool CPoint::InRect(const CRect& rc) const {
return rc.ptIn(*this);
}
void CPoint::Draw() const {
circle(m_nPosX, m_nPosY, 2);
}
void CPoint::DrawColor(){
}
CPoint* CPoint::Clone() const {
return new CPoint(*this);
}
CPoint& CPoint::Move(int nOffsetX, int nOffsetY) {
m_nPosX += nOffsetX;
m_nPosY += nOffsetY;
return *this;
}
//CTriangle
CTriangle::CTriangle(const CTriangle& tri) {
for (int i = 0; i < 3; i++) {
m_pts[i] = tri.m_pts[i];
}
}
CTriangle::~CTriangle() {
//cout << "CTriangle::~CTriangle()\n";
}
CTriangle::CTriangle(const CPoint& pt1, const CPoint& pt2, const CPoint& pt3) {
m_pts[