当前位置: 首页 > news >正文

C++ QT设计模式 (第二版)

        第3章 Qt简介

                3.2 Qt核心模块

        Qt是一个大库,由数个较小的库或者模块组成,最为常见的如下:core、gui、xml、sql、phonon、webkit,除了core和gui,这些模块都需要在qmake的工程文件中启用

        QTextStream 流,Qdate 日期

                3.3 Qt Create,用于Qt编程的集成开发环境

        在Qt软件开发包 (Qt Software Development Kit,SDK)中包含有Qt Creator,其中包含了Qt和快速开始使用Qt 进行开发工作的所有东西

        可使用拖放窗体布局来完成设计的Qt设计师也完全集成到了Qt Creator中

        Qt Creator 用到的项目文件是 qmake 的.pro 文件,通过创建或编辑Qt Creator中已有的项目文件,可以完全避免命令行工具的使用

        第4章 列表

        只要有可能 ,就应当使用列表而不是数组

                4.1  容器

        列表 QList

                4.2、迭代器

        迭代器是一个提供对容器中的每一个元素进行间接访问的对象,它专门被设计用于在循环之中,三种迭代器模式:foreach循环,C++迭代器,Java风格的迭代器

        QStringList  实际上就是一个QList<QString>,使用split()函数和join()函数,在列表与字符串之间进行转换 相当简单

#include <QStringList>
#include <QDebug>int main()
{QString winter = "December, January, February";QString spring = "March, April, May";QStringList list;list += winter;list.append(spring);qDebug() << list;QString test = list.join(","); //list转换字符串qDebug() << test;QStringList list2 = test.split(",");//字符串转换listqDebug() << list2;Q_ASSERT(list2.size() == 6 );foreach (const QString &str, list2) { //foreach循环qDebug() << QString(" [%1] ").arg(str);}for(QStringList::iterator it = list2.begin();//C++迭代器it!=list2.end(); ++it){qDebug() << *it;}QListIterator<QString> itr( list2 );//Java风格的迭代器while(itr.hasNext()){qDebug() << itr.next();}return 0;
}

        目录(有时称为文件夹),是文件的容器,目录可以包含符号链接,指向另外的文件或目录,对于处理文件或目录的大多数操作,可以使用符号链接而不是文件名称或路径名称

        QDir 和 QDirIterator

#include <QDebug>
#include <QDir>
#include <QDirIterator>int main()
{QDir dir = QDir::current(); // QDir 类的静态成员函数current,成员函数 absolutePathQDirIterator qdi (dir.absolutePath(), QDir::NoDot|QDir::Files, QDirIterator::Subdirectories);while(qdi.hasNext()){ //hasNext、next 是 QDirIterator 类的成员函数qDebug() << qdi.next();}return 0;
}
                4.3 关系

        三种关系:关联(只用于导航性)、聚合(无管理的包含关系)、组合(带管理的包含关系)

        第7章 库与设计模式

        库是一组代码模块,它按照可复用的方式组织,代码库中保存的是有用的、可复用的、编译后的代码,当用#include指令包含库模块的头文件时,就可以复用这个库模块

        当复用来自于库中的任何模块时,其工作由链接器linker在链编build过程完成,可执行文件必须在运行时找到并动态地链接到编译后的库(称为运行时库),库lib是一个文件,它包含一个或者多个编译后文件,并对其进行了索引

        C++库能够以多种途径被打包:开源包 通常以压缩的档案文件形式发布,它包含全部的源代码、头文件以及链编脚本和文档;dev包 在Linux包管理程序中有时被称为-devel包,它通常以档案文件的形式发布,包含一个库以及相关的头文件运行时库 由lib文件组成,没有相关联的头文件,所以它只能用于执行已经用这个库链编过的应用

                7.1 建立并复用库

        qmake可以在工程文件里访问CPPLIBS环境变量,其访问语法是 $$(CPPBLIBS),qmake也可以包含其他的工程文件(片段)      

         工程为 LIBS INCLUDEPATH 变量 添加一些值,使它能够找到所 依赖的库和头文件,qmake无法知道用来构建工程所需要的外部库,如果工程依赖于某个外部库,则必须编辑这个工程文件,将它的值赋予变量INCLUDEPATH和LIBS

        假设应用所需使用dataobjects库,其头文件位于$CPPLIBS/dataobjects下,共享目标文件的库位于$CPPLIBS下,那么必须如下这些行添加到工程文件中:

INCLUDEPAHT += $$(CPPLIBS)/dataobjects   #头文件
LIBS += -L$$(CPPLIBS)  # lib 搜索路径
LIBS += -ldataobjects  # link with libdataobjects.so

        组织库:依赖性管理,对于类,只要被复用者类的接口发生改变,就使得复用者的实现必须改变,则它们之间就存在依赖性:编译时依赖 和 链接时依赖,当设计类和库时,需要确保尽可能地减少不必要的或者无意的依赖性,对于类定义头文件,需遵循的一条规则是:如果可以使用 前置声明,就不要使用#include指令

        安装库:当编写并测试完库之后,在链编过程结束后,它将被安装到由qmake变量DESTDIR指定的目录下,如果要迁移库,在windows系统中,可以将它的.dll文件复制到PATH变量中给出的合适目录下

                7.3 框架与组件

         在现代编程技术中,代码复用具有最高优先级,框架是一个通用类与约定的集合,其目的是提高设计的一致性,框架一般都具有文档丰富的公共API,API是库中公共函数、类和接口的描述,为了实现框架,可以采取设计模式

        Qt是许多开源的面向对象框架中的一种,它提供一组可复用的组件,用于创建跨平台的应用 

                7.4 设计模式

        设计模式可用于许多不同场合,其中 的大多数都描述如何根据职责来区分代码,这些模式被分成 三种 类别:创建模式、结构模式、行为模式 

        序列化器模式:QTextStream 和 QDataStream,序列化器是一种只负责读取或者写入对象的对象,Qt的QTextStream序列化器用于读写人可读的文件,而QDataStream序列化器用于读写结构化的二进制数据,这些类用 序列化模式 实现的,被用于C++和Qt中,序列化器模式的思想是将I/O代码与类本身分开

         反模式:软件设计反模式:输入杂乱、接口膨胀、竞争风险,面向对象设计反模式:循环依赖性、“上帝”对象(具有太多信息或者太多责任的对象),编程反模式:难以编码、魔幻数字、魔幻字符串,方法学反模式:复制--粘贴编程、一切从头开始 

        第8章  QObject,QApplication,信号和槽

        QObject 是Qt库中许多重要的类的基类,如QEvent,QApplication,QLayout和QWIDget,一个QObject可以有一个父对象和一些子对象,这是组合模式的另一种实现方式,它可以使用信号和槽,即观察者模式的一种实现,与其他QObject通信

        QObject没有公有的复制函数或复制赋值运算符,向下到QObject类定义的结尾处有一个宏Q_DISABLE_COPY(QObject),它显式地确保任何QObject都不能被复制,这种不带复制构造函数策略的一个直接后果就是永远无法通过值传递方式向函数传递QObject 

        每个QObject都可以有(至多)一个父QObject,且可以拥有任意数量的子QObject,每个QObject都将指向各个子对象的指针存放在一个QObjectList中 

        每个QObject父对象都会管理自己的子对象,在调用QObject的析构函数时会自动销毁该对象的子对象,子对象列表会在各个QObject对象之间建立一种双向的关联:每个父对象都知道它的子对象的地址,每个子对象都知道其父对象的地址

        给某个对象设置父对象,将会隐含地把此对象添加到父对象的子对象列表之中重父化:把A对象设置B对象为父对象,会把A对象指针添加到B的子列表中,如果再把A对象设置C对象为父对象,A的指针会从B的子列表中删除,然后添加到C的子列表中

        不应将父对象和基类混为一谈,父--子关系是为了描述对象运行时的约束和管理关系,基类派生关系是编译时各个类进行判定的一种静态关系 

        没有父对象的QObject应当在程序栈区中进行定义,哪些有父对象的QObject则应当在堆区动态创建出来

                8.1 值和对象

        C++类型可以分成两类:值类型和对象类型

        值类型的例子有:Anything*,int,char,QString,QDate 和 QVariant(QVariant是一种特殊的联合体类型,可保存所有可复制的内置类型和编程人员定义的类型,QVariant已支持的类型:QList,QImage,QString,QMap,QHash类型),带有公有默认构造函数、复制构造函数和复制赋值运算符的任何类都是值类型的,QObject 的设计人员毫不犹豫地采用了“无复制”策略,该方法就是将赋值运算符与复制构造函数设置为private类型

        在栈区创建 QList、QString、QHash、QImage或者其他 与 QVariant相关类型,Qt为你完成引用计数和内存管理

                8.2 组合模式:父对象和子对象

         复合对象是包含可以包含子对象的类,组件对象是可以拥有一个父对象的类,许多Qt类都用到了组合模式:QObject、QWIDget、QTreeWidgetItem、QDomNode、QHelpContentItem和QResource,在任何基于树的结构体中都可以找到组合模式

        每个QObject都可以有不限数量的QObject子对象,这些子对象的地址会存放在一个特殊的QObject指针容器内,子对象在该列表中的出现次序是它们在添加到该列表中时的次序,QObject还提供两个名称为findChildren()的重载(递归)函数,每个都会返回一个满足特定条件的子对象列表

                8.3 QApplication和事件循环

        观察者模式,当任意数据模型对象发生状态改变时,就需要一种间接的方式来提醒观察者,观察者就是一些正在监听状态变化事件的对象

        Qt的QEvent类封装了底层事件的概念,QEvent类是若干特定的事件类的基类,QEvent对象可以由窗口系统创建以响应用户的动作,事件循环是一个程序结构,它能够将事件划分优先级,排队并分派给一些对象,事件循环通常会一直运行,直到遇到某个终止事件,QApplication::exec()函数,应用程序的这个工作部分开始于该函数的调用,终止于该函数的返回

        事件可认为是低级消息,目标是某个特定的对象,信号可以认为是高级消息,很可能会连接到许多槽上,只有在事件循环,信号才发送到槽上,这里的信号是指对事件进行封装的信号

                8.4  Q_OBJECT 

        QObject 支持一些普通C++对象通常所没有的特性:信号和槽;元对象、元属性、元方法;qobject_cast

         编写C++代码和qmake工程文件时应该遵守的一些指导原则:每个类的定义都应该放在各自对应的.h文件中;每个类的实现都应当放在相应的.cpp文件中;为避免头文件的多次包含,头文件应该封装起来;每个.cpp源文件都应当列举在工程文件的SOURCES变量中;每个头文件都应当列举在.pro工程文件的HEADERS变量中;Q_OBJECT宏必须出现在每个QObject派生类定义的头文件中

        每个Q_OBJECT宏都会产生代码,需要使用元编译器moc进行预处理,QObject类应该是其基类列表中的第一个基类

                8.5 信号和槽

        信号是在类定义中给出的,类似于void函数声明的一种消息,它有参数列表却没有函数体,信号是一个类的接口的一部分,它看起来像函数,但不用同样的方式进行调用---它被此类的对象发射

        槽通常是一个void成员函数,它可以像普通的成员函数一样进行调用,或者可以由QMetaObject系统进行间接调用 

         一个对象的信号可以与一个或多个对象的槽相连接,前提是这些对象存在并且参数列表从信号到槽都是赋值兼容的

相关文章:

C++ QT设计模式 (第二版)

第3章 Qt简介 3.2 Qt核心模块 Qt是一个大库&#xff0c;由数个较小的库或者模块组成&#xff0c;最为常见的如下&#xff1a;core、gui、xml、sql、phonon、webkit&#xff0c;除了core和gui&#xff0c;这些模块都需要在qmake的工程文件中启用 QTextStream 流&#xff0c;Qdat…...

【经验总结】超算互联网服务器 transformers 加载本地模型

1. 背景 使用 超算互联网 的云服务&#xff0c;不能连接外网&#xff0c;只能把模型下载到本地&#xff0c;再上传上去到云服务。 2. 模型下载 在 模型中 https://huggingface.co/models 找到所需的模型后 点击下载 config.json pytorch_model.bin vocab.txt 3. 上传模型文…...

ubuntu编译pcl时报错

报错如下 cc1plus: warning: -Wabi wont warn about anything [-Wabi] cc1plus: note: -Wabi warns about differences from the most up-to-date ABI, which is also used by default cc1plus: note: use e.g. -Wabi11 to warn about changes from GCC 7 在网上找到了一封邮件…...

Rust中的单元测试

概述 Rust内置了单元测试的支持&#xff0c;这点和Golang一样&#xff0c;非常的棒&#xff0c;我超级喜欢单元测试&#xff01;&#xff01;&#xff01; 本节课的代码还是基于之前的求公约数的案例。 之前的完整代码如下&#xff1a; fn gcd(mut n: u64, mut m: u64) ->…...

ubuntu18.04系统安装pangolin

1. 安装pangolin依赖项 ctrlaltt 打开终端&#xff0c;依次输入下面的命令 sudo apt update sudo apt upgrade sudo apt install libglew-dev cmake libboost-dev libboost-thread-dev libboost-filesystem-dev libeigen3-dev -y 2.在终端中输入下面的命令&#xff0c;克隆…...

洛谷P10397题解

题目描述 给定一条 std::freopen 语句&#xff0c;输出其操作的文件名称。 形式化地&#xff0c;std::freopen 语句都应该恰好是 std::freopen("<title>","<mode>",<stream>);其中 <title> 为其操作的文件名称。其至少包含一个…...

【Linux】自动化编译工具——make/makefile(超细图例详解!!)

目录 一、前言 二、make / Makefile背景介绍 &#x1f95d;Makefile是干什么的&#xff1f; &#x1f347;make又是什么&#xff1f; 三、demo实现【见见猪跑&#x1f416;】 四、依赖关系与依赖方法 1、概念理清 2、感性理解【父与子&#x1f468;】 3、深层理解【程序…...

goroutine调度策略

Golang的调度器采用M:N调度模型&#xff0c;其中M代表用户级别的线程(也就是goroutine)&#xff0c;而N代表的事内核级别的线程。Go调度器的主要任务就是N个OS线程上调度M个goroutine。这种模型允许在少量的OS线程上运行大量的goroutine。 Go调度器使用了三种队列来管理gorout…...

TypeScript中`unknown`的使用场景:安全处理未知类型

TypeScript中unknown的使用场景&#xff1a;安全处理未知类型 引言 在TypeScript中&#xff0c;unknown类型是除了any类型之外的另一种选择&#xff0c;它用于表示一个值可能是任何类型。与any不同&#xff0c;unknown提供了一种更安全的方式来处理未知的数据&#xff0c;因为…...

react18【系列实用教程】JSX (2024最新版)

为什么要用 JSX&#xff1f; JSX 给 HTML 赋予了 JS 的编程能力 JSX 的本质 JSX 是 JavaScript 的语法扩展&#xff0c;浏览器本身不能识别&#xff0c;需要通过解析工具&#xff08;如babel&#xff09;解析之后才能在浏览器中运行。 bable 官网可以查看解析过程 JSX 的语法 …...

Docker 创建网络

问题&#xff1a; 1.需要将多个容器添加到同一个网络. 2.docker-compose.yaml 如果不指定&#xff0c;默认会重新创建一个网卡. 创建网卡 docker network create -d bridge mynet ##-d 指定模式&#xff08;默认桥接&#xff09;查看自定义网络信息 docker inspect mynet…...

ASME美国机械工程师学会文献如何查询下载经验分享

一、ASME美国机械工程师学会数据库简介&#xff1a; ASME是世界上最大的技术出版机构之一&#xff0c;制定众多的工业和制造业行业标准。现在ASME拥有工业和制造行业的600项标准和规范&#xff0c;这些标准在全球90多个国家被采用。 ASME数据库包含25种专业期刊&#xff0c;其…...

Spring MVC分页示例

Spring MVC分页示例 分页用于在不同部分显示大量记录。在这种情况下&#xff0c;我们将在一页中显示10、20或50条记录。对于其余记录&#xff0c;我们提供链接。 我们可以在Spring MVC中简单地创建分页示例。在此分页示例中&#xff0c;我们使用MySQL数据库来获取记录。 创建…...

C++基础——继承(上)

一、继承的概念 继承 (inheritance) 机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许实现者保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称之为派生类&#xff1b; 继承呈现了面向对象程序设计的层次结构…...

编译安装Python3

1、源码安装 1、安装依赖软件包 yum -y install gcc gcc-c zlib-devel bzip2-devel openssl-devel sqlite-devel readline-devel libffi-devel # python3.7版本安装 2、下载 curl -o python3.6.5.tgz https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz // 或者 w…...

MySQL数据库核心面试题

数据库中的引擎 常用的引擎有InnoDB、MyIsam、Memory三种。 MyIsam&#xff1a;组织形式分为三种&#xff1a; frm文件存储表结构、MyData文件存储表中的数据、MyIndex文件存储表的索引数据。是分开存储的。 Memory&#xff1a;基于内存的&#xff0c;访问速度快&#xff0…...

Golang | Leetcode Golang题解之第85题最大矩形

题目&#xff1a; 题解&#xff1a; func maximalRectangle(matrix [][]byte) (ans int) {if len(matrix) 0 {return}m, n : len(matrix), len(matrix[0])left : make([][]int, m)for i, row : range matrix {left[i] make([]int, n)for j, v : range row {if v 0 {continu…...

Linux基础知识面试题

1. 请描述Linux操作系统的安装过程&#xff0c;并说明其中的关键步骤。 Linux操作系统的安装过程通常涉及以下几个关键步骤&#xff1a; 准备安装介质&#xff1a;需要从官网或者其他可靠来源下载Linux发行版的ISO镜像文件&#xff0c;并制作一个启动U盘或者烧录到DVD中。现在…...

中国高分辨率国家土壤信息网格基本属性数据集(2010-2018)

中国高分辨率国家土壤信息网格基本属性数据集&#xff08;2010-2018&#xff09; 数据介绍 土壤是人类生存和发展的基础&#xff0c;多个联合国可持续发展目标&#xff08;SDGs&#xff09;与土壤资源利用和管理直接相关。然而&#xff0c;全球和我国现有土壤信息大多源于历史土…...

数据仓库项目---Day01

文章目录 框架的安装包数据仓库概念项目需求及架构设计项目需求分析项目框架技术选型系统数据流程设计框架版本选型集群资源规划设计 数据生成模块数据埋点主流埋点方式埋点数据上报时机 服务器和JDK准备搭建三台Linux虚拟机(VMWare)编写集群分发脚本xsyncSSH无密登录配置JDK准…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...