配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
1. 断言断言(assertion)是一种编程中常用的手段。在通常情况下,断言就是将一个返回值总是需要为真的判断表达式放在语句中,用于排除在设计的逻辑上不应该产生的情况。
比如:一个函数总需要输入在一定的范围内的参数,那么程序员就可以对该参数使用断言,以迫使在该参数发生异常的时候程序退出,从而避免程序陷入逻辑的混乱。
从一些意义上讲,断言并不是正常程序所必需的,不过对于程序调试来说,通常断言能够帮助程序开发者快速定位那些违反了某些前提条件的程序错误。
如果我们要在C++程序中使用断言,需要在程序中包含头文件<cassert>或<assert.h>,头文件中为我们提供了 assert 宏,用于在运行时进行断言。举例说明:
12345678910111213141516171819202122#include <iostream>#include <cassert>using namespace std;// 创建 ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
1. 类与默认函数在C++中声明自定义的类,编译器会默认帮助程序员生成一些他们未自定义的成员函数。这样的函数版本被称为”默认函数”。这样的函数一共有六个,我们一起来看一下:
无参构造函数:创建类对象
拷贝构造函数:拷贝类对象
移动构造函数:拷贝类对象
拷贝赋值函数:类对象赋值
移动赋值函数:类对象赋值
析构函数
:销毁类对象
在C++语法规则中,一旦程序员实现了这些函数的自定义版本,则编译器不会再为该类自动生成默认版本。
有时程序员会忘记上面提到的规则,最常见的是声明了带参数的构造,如果还需要无参构造函数,这时候必须定义出不带参数的版本。不过通过编译器的提示,这样的问题通常会得到更正。但更为严重的问题是,一旦声明了自定义版本的构造函数,则有可能导致我们定义的类型不再是POD类型,我们便不再能够享受POD类型为我们带来的便利。
对于上面提到的这些,我们无需过度担心,因为C++11非常贴心地为我们提供了解决方案,就是使用=default 。
2. = ...
配套视频课程已更新完毕,大家可通过以下两种方式观看视频讲解:
关注公众号:爱编程的大丙,或者进入大丙课堂学习。
1. POD 类型POD是英文中 Plain Old Data 的缩写,翻译过来就是普通的旧数据 。POD在C++中是非常重要的一个概念,通常用于说明一个类型的属性,尤其是用户自定义类型的属性。
POD属性在C++11中往往又是构建其他C++概念的基础,事实上,在C++11标准中,POD出现的概率相当高。因此学习C++,尤其是在 C++11中,了解 POD的概念是非常必要的。
Plain :表示是个普通的类型
Old :体现了其与C的兼容性,支持标准C函数
在C++11中将 POD划分为两个基本概念的合集,即∶平凡的(trivial) 和标准布局的(standard layout ) 。
2. “平凡”类型一个平凡的类或者结构体应该符合以下几点要求:
拥有平凡的默认构造函数(trivial constructor)和析构函数(trivial destructor)。
平凡的默认构造函数就是说构造函数什么都不干。
通常情况下,不定义类的构造函数,编译 ...
在项目开发过程中,如果涉及到数据的存储,那么肯定会用到数据库。常用的关系型数据库(操作的时候需要使用sql语句)有:mysql、oracle、sqllite等。在Qt框架中也同样提供了对这些数据库的支持,我们使用Qt提供的数据库类就可以在上层使用相同的接口对各种数据库进行操作了,非常的nice。
关于在程序中连接数据库有很多种处理方式,比如:odbc、ado等,在Qt底层也对数据库的连接进行了封装,基于不同的连接方式为我们提供了不同的插件(二进制代码,在需要的时候被加载,表现形式为动态库、静态库)。虽然如此,但是有一点很杯具:在高版本的Qt中官方并没有为我们提供可用的mysql和oralce插件,只提供了源代码(不能直接使用),需要我们基于这些源码自行编译得到对应的动态库(静态库)之后,才能被程序加载从而连接上相应的数据库。
由于mysql是我们日常工作和学习中用的最多的一种数据库,所以下面为大家讲解一下如何在 Qt 中编译出可用的 MySql 插件。
本文演示使用的版本说明:
使用的IDE:QtCreator
Qt 版本:5.15.2
数据库版本:MySql 8.0.27 ...
1. 游戏概述
1.1 游戏简介“斗地主”是流行于湖北一带的一种扑克游戏,玩法简单,娱乐性强,老少皆宜。据传在万恶的旧社会,地主横行乡里,无恶不做,人们为了发泄对地主的痛恨,常常在一天的劳作之后,一家人关起门来“斗地主”。
1.2 游戏类型V1.0 版游戏是第一个版本为单机版,主要是用户和机器人对战。
后续会开发出网络版……
2. 游戏规则不同地域游戏规则可能有些许差异,游戏按照如下规则进行实现。
2.1 牌型
牌型
描述
王炸
大王+小王,最大的牌
炸弹
四张同数值牌(如四个 9)
单牌
单张的牌(如红桃 3 )
对牌
数值相同的两张牌(如梅花 4+ 方块 4 )
三张牌
数值相同的三张牌(如三个 Q )
三带一
数值相同的三张牌 + 1张单牌,例如: 333+6
三带二
数值相同的三张牌 + 1对牌,例如: 666+33
顺子
五张或更多的连续单牌,不包括 2 和双王
连对
三对或更多的连续对牌,不包括 2 和双王
飞机
二个或更多的连续三张牌,不包括 2 和双王
飞机带翅膀
飞机+同数量的单牌(或同数量的对牌)
四带二
...
C++
未读关于Json这种数据格式,在前面已经做了详细的介绍 Json的格式和用途,在项目开发过程中我们需要针对不同的语言使用不同的库对Json格式的数据进行解析,下面给大家介绍一个基于C语言的Json库 – cJson。cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。
cJSON 是一个开源项目,github下载地址:https://github.com/DaveGamble/cJSON
cJSON,目前来说,主要的文件有两个,一个cJSON.c 一个cJSON.h。使用的时候,将头文件include进去即可。如果是在Linux操作系统中使用,编译 到时候需要添加数学库libm.so,如下所示:
1gcc *.c cJSON.c -lm
1. cJSON结构体在cJSON.h中定义了一个非常重要的结构体cJSON,想要熟悉使用cJSON库函数可从cJSON结构体入手,cJSON结构体如下所示:
123456789typedef struct cJSON { struct cJSON *next,*prev; ...
在 Json的两种格式中介绍了Json的格式以及应用场景。由于这种数据格式与语言无关,下面介绍一下Json在Qt中的使用。
从Qt 5.0开始提供了对Json的支持,我们可以直接使用Qt提供的Json类进行数据的组织和解析。相关的类常用的主要有四个,具体如下:
Json类
介绍
QJsonDocument
它封装了一个完整的JSON文档,并且可以从UTF-8编码的基于文本的表示以及Qt自己的二进制格式读取和写入该文档。
QJsonArray
JSON数组是一个值列表。可以通过从数组中插入和删除QJsonValue来操作该列表。
QJsonObject
JSON对象是键值对的列表,其中键是唯一的字符串,值由QJsonValue表示。
QJsonValue
该类封装了JSON支持的数据类型。
1. QJsonValue在Qt中QJsonValue可以封装的基础数据类型有六种(和Json支持的类型一致),分别为:
布尔类型:QJsonValue::Bool
浮点类型(包括整形): QJsonValue::Double
字符串类型: QJsonValue::Str ...
JSON(JavaScrip Object Notation)是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
关于上面的描述可以精简为一句话:Json是一种数据格式,和语言无关,在什么语言中都可以使用Json。基于这种通用的数据格式,一般处理两方面的任务:
组织数据(数据序列化),用于数据的网络传输
组织数据(数据序列化),写磁盘文件实现数据的持久化存储(一般以.json作为文件后缀)
Json中主要有两种数据格式:Json数组和Json对象,并且这两种格式可以交叉嵌套使用,下面依次介绍下这两种数据格式:
1. Json数组Json数组使用 [] 表示,[]里边是元素,元素和元素之间使用逗号间隔,最后一个元素后边没有逗号,一个Json数组中支持同时存在多种不同类型的成员,包括:整形、 浮点、 字符串、 布尔类型、 json数组、 json对象、 空 ...
1. Qt程序的发布当Qt程序编写完成通过IDE编译就可以得到对应的可执行程序,这个可执行程序在本地运行是完全没有问题的(因为在本地有Qt环境,程序运行过程中可以加载到相关的动态库),但是如果我们想把这个Qt程序给到其他小伙伴使用可能就会出问题了,原因如下:
这个小伙伴本地根本没有Qt开发环境
这个小伙伴本地有Qt开发环境,但是和我们使用的版本不一致
这个小伙伴本地有Qt开发环境并且使用的版本与我们一致,但是没有配置环境变量
以上几种情况都会导致我们的小伙伴拿到可执行程序之后无法运行,下面来给大家讲一下解决方案。
1.1 生成Release版程序在编写Qt程序的时候,不管我们使用的什么样的IDE都可以进行编译版本的切换,如果要发布程序需要切换为Release版本(Debug为调试版本),编译器会对生成的Release版可执行程序进行优化,生成的可执行程序会更小。这里以QtCreator为例,截图如下:
模式选择完毕之后开始构建当前项目,最后找到生成的带Release后缀的构建目录,如下图所示:
进图到release目录中,在里面就能找到我们要的可执行程序了
1.2 ...
1. 事件过滤器除了使用事件分发器来过滤Qt窗口中产生的事件,还可以通过事件过滤器过滤相关的事件。当Qt的事件通过应用程序对象发送给相关窗口之后,窗口接收到数据之前这个期间可对事件进行过滤,过滤掉的事件就不能被继续处理了。QObject有一个eventFilter()函数,用于建立事件过滤器。函数原型如下:
1[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event);
参数:
watched:要过滤的事件的所有者对象
event:要过滤的具体的事件
返回值:如果想过滤掉这个事件,停止它被进一步处理,返回true,否则返回 false
既然要过滤传递中的事件,首当其冲还是要搞明白如何通过事件过滤器进行事件的过滤,主要分为两步:
给要被过滤事件的类对象安装事件过滤器
1void QObject::installEventFilter(QObject *filterObj);
假设调用installEventFilter()函数的对象为当前对象,那么就可以基于参数指定的filterObj对象来过滤当 ...