2,114
社区成员




目录
C++课程设计和C课程设计要写的软件内容差不多,主要区别在于设计思路。C是面向过程的语言,很多操作都设计成一个个单独的函数;而C++是面向对象的语言,设计上要以类这个概念为中心,将数据和操作封装在一起,形成一个个类。
我记得当年笔者的小组验收时,老师问了这样一个问题:你们的程序中有没有用到类?有没有用到继承、多态?所以想拿高分的同学注意了,要多使用面向对象中的特性,体现你对知识点的掌握。当然,实现功能是最首要的目的。
写一个工程,最重要的就是要知道:我要写一个什么东西?
举一个现实中的例子。bilibili是一个视频网站,而如今有很多产品经理批评bilibili的定位不清晰,功能混杂。所以方向歪了,之后走的每一步都很艰难。
我们第一个要考虑的问题是:学生成绩管理系统是什么?它的功能是什么?它能做什么,它不能做什么?
那么我们可以从哪些渠道来知道它的功能呢?
关于选题,大体上分为两类。一类是系统,另一类是游戏。难易度来讲,系统的逻辑稍复杂而界面好写;游戏的界面难写而逻辑简单。不过更主要一点是,游戏写完了可以拿来自己玩,开发过程中还是挺有趣的。当年笔者小组写了五子棋,有人机对战功能,笔者只赢了一次T.T
用面向对象语言进行设计,当然要思考有哪些对象。这里我们可以把学生、课程、成绩都看作对象,那么我们就可以这样设计:
// student.h
#include <string>
class Student{
private:
int id;
std::string name;
public:
Student(int id = -1, std::string name = "");
Student(const Student& s);
~Student();
// getter and setter
int getId();
void setId(int id);
std::string& getName();
void setName(std::string& name);
};
// course.h
#include <string>
class Course{
private:
int id;
std::string name;
public:
Course(int id = -1, std::string name = "");
Course(const Course& c);
~Course();
// getter and setter
int getId();
void setId(int id);
std::string& getName();
void setName(std::string& name);
};
// score.h
class Score{
private:
int student_id;
int course_id;
int score;
public:
Score(int student_id = -1, int course_id = -1, int score = -1);
Score(const Score& s);
~Score();
// getter and setter
int getStudentId();
void setStudentId(int student_id);
int getCourseId();
void setCourseId(int course_id);
int getScore();
void setScore(int score);
};
设计类时工业上有很多规范,大家可以上网查资料学习,写出来的代码当然是越规范越好。
那么如何把继承加进去呢?我们可以将课程细分为必修课和选修课,那么我们可以这样设计:
// course.h
#include <string>
class Compulsory : public Course{
private:
int credit;
int hours;
public:
Compulsory(int id = -1, std::string name = "", int credit = -1, int hours = -1);
Compulsory(const Compulsory& c);
~Compulsory();
// getter and setter
int getCredit();
void setCredit(int credit);
int getHours();
void setHours(int hours);
};
class Elective : public Course{
private:
int credit;
int hours;
public:
Elective(int id = -1, std::string name = "", int credit = -1, int hours = -1);
Elective(const Elective& e);
~Elective();
// getter and setter
int getCredit();
void setCredit(int credit);
int getHours();
void setHours(int hours);
};
但其实发现在简单的情况下,这两个派生类没什么区别,不如在class Course
中加一个成员变量bool compulsory
,表示是否为必修课。其实在软件工程领域中,这两种设计方案也是有说法的,但是这里不展开讨论了。
设计方面,有C语言课设的经验,想必大家应该多多少少心里有点谱,笔者就不赘述了。
STL是C++的标准库,里面有很多好用的东西,很多数据结构都是写好的。如动态数组vector
、链表list
、栈stack
、队列queue
、映射表map
等等。这些数据结构都是模板类,可以存放任意类型的数据。还有很多算法,如排序、二分查找等。
比如说,我们要对学生进行排序,那么我们可以这样写:
// main.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include "student.h"
int main(){
std::vector<Student> students;
students.push_back(Student(2, "李四"));
students.push_back(Student(1, "张三"));
students.push_back(Student(4, "赵六"));
students.push_back(Student(3, "王五"));
// sort
// 这里需要在Student类内实现operator<的重载
std::sort(students.begin(), students.end());
// print
for(auto s : students)
std::cout << s.getId() << " " << s.getName() << std::endl;
}
上例只是冰山一角,STL的功能非常强大,大家可以自行学习。下面列举几个常用的数据结构。看头文件
#include <array> // 静态数组,数组长度不可变
#include <vector> // 动态数组,数组长度可变
#include <list> // 链表
#include <stack> // 栈
#include <deque> // 双端队列
#include <queue> // 队列,内含普通队列、优先队列(priority_queue)
#include <map> // 映射表,内含有序映射表、无序映射表(unordered_map)
#include <set> // 集合,内含红黑树集合、哈希集合(unordered_set)
#include <algorithm> // 算法,内含排序(sort)、二分查找(binary_search)等
由于C++课程设计要求图形界面,接下来介绍两个常用的用来写界面的库。一个是本节提到的EasyX,另一个是Qt。这俩的区别简单粗暴地来讲,EasyX是过家家,Qt是商业级的。EasyX的优点是简单易用,缺点是功能不够强大;Qt的优点是功能强大,缺点是学习成本高。
也是从这里开始,希望大家可以逐渐开始阅读官方文档,进行自学。这是一个程序员的必备技能。不是所有的库都有教科书或博客这类教程来教,有些小众的库可能只有一个官方文档。常见的官方文档名称有:"documentation"、"manual"、"guide"、"tutorial"等等,还有一些带你入门的文章如"Getting Started"、"Quick Start"等等。可以留意一下。
EasyX是一个基于Windows GDI的简单易用的图形库,可以用来写图形界面。它的官网是:https://easyx.cn/。它的使用方法很简单,大家可以自行学习。
Qt是一个跨平台的C++图形界面库,它的官网是:https://www.qt.io/。Qt的入门较为复杂,不过想在课程设计期间用Qt来交差还是可以的。笔者对Qt较为熟悉,推荐一些学习资料
一些需要注意的点
Build System
步骤将CMake改成qmake,这样看起来就和教程一样了。windeployqt
命令进行部署。假设生成的可执行文件为main.exe
,具体操作如下。在工程根目录下新建文件夹bin/
,把main.exe
复制到bin/
下。打开Qt文件夹下的命令行,定位到bin/
,输入这条命令:windeployqt main.exe
。这样就会自动把main.exe
所需要的dll文件复制到bin/
下。然后就可以把bin/
下的文件打包发给老师或助教了。否则老师或助教打不开你的程序。Visio是一个作图软件,可以用来画流程图、UML图、电路图等等。作为oop课程设计,报告里应该有一项要求是画UML图的,推荐使用Visio来画。未来四年的学习生涯中,可能还会用到Visio,所以建议大家学会使用。(比如数字电路、软件工程、Python/Java等oop)Visio是较为专业的软件,上手比较复杂,不过熟悉了后会非常好用,建议尽早熟悉。
Visio没有社区版,不过破解版也很好找滴。
实在嫌麻烦可以使用在线作图工具,如https://www.processon.com/
鉴于C++课程设计要求图形界面,而图形界面编程面临着从头开始学的问题,大部分小组会安排一个专人去写。然而写图形界面往往与工程的核心功能没什么关系,如果对Qt不是很熟悉,甚至不会用到自定义控件,则不会涉及到类继承多态等问题。所以可能拿不到4.5分。最主要的在于,Qt编程一般不是设计类,而是使用类。不过念在GUI编程麻烦的份上,老师可能会给个3.5分。(纯个人经验,甚至连身边的统计学家都算不上QAQ)
感谢大家的阅读,希望本文能对大家有所帮助。如果有任何问题,欢迎在评论区留言。