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

news2024/11/17 23:47:23

        第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(",");//字符串转换list
    qDebug() << 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,成员函数 absolutePath
    QDirIterator 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系统进行间接调用 

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1676103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

本地安装nvm,管理多版本node

先卸载本地的nodejs(14.16.1) 卸载的直接可以点击win10图标→设置→应用→应用和功能 卸载nodejs即可 2. 安装nvm&#xff0c;地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 安装目录时尽量不要出现特殊字符还有空格&#xff0c;否则会在nvm use xxx的…

海外媒体发稿:如何在日本媒体投放新闻通稿-大舍传媒

导言 在全球化的时代背景下&#xff0c;海外媒体宣发对于企业来说非常重要。通过在海外媒体投放新闻通稿&#xff0c;企业能够拓展海外市场&#xff0c;增强知名度和影响力。本文将探讨如何在海外媒体投放新闻通稿&#xff0c;以帮助企业进行有效的海外宣传。 挖掘海外媒体资…

Alibaba SpringCloud集成Nacos、Sentinel实现服务治理-17

关于服务治理 总体而言&#xff0c;限流和降级作为微服务架构中的重要机制&#xff0c;尽管在实现上可能有多种方式&#xff0c;但它们都着眼于保护服务提供者和消费者&#xff0c;在面对异常情况时确保系统稳定运行。限流关注于保护服务提供者&#xff0c;控制请求流量&#…

20232810 2023-2024-2 《网络攻防实践》实验九

一、实践内容 1.1 反汇编 1.1.1 编程原理 编程的原理是一套指导软件开发和维护的概念、原则和实践&#xff0c;包括抽象以简化复杂系统、模块化以分解程序、封装以隐藏内部状态、继承以共享特性、多态以允许不同响应、算法和数据结构以组织计算和存储、控制结构以控制流程、…

UVa11419 SAM I AM

UVa11419 SAM I AM 题目链接题意分析AC 代码 题目链接 UVA - 11419 SAM I AM 题意 给出一个 RC 大小的网格&#xff0c;网格上面放了一些目标。可以在网格外发射子弹&#xff0c;子弹会沿着垂直或者水平方向飞行&#xff0c;并且打掉飞行路径上的所有目标&#xff0c;如下图所…

System V IPC(进程间通信)机制详解

文章目录 一、引言二、System V IPC的基本概念1、IPC结构的引入2、IPC标识符&#xff08;IPC ID&#xff09;3、S ystem V的优缺点 三、共享内存&#xff08;Shared Memory&#xff09;1、共享内存的基本概念2、共享内存的创建&#xff08;shmget&#xff09;3、共享内存的附加…

深入探索Android签名机制:从v1到v3的演进之旅

引言 在Android开发的世界中&#xff0c;APK的签名机制是确保应用安全性的关键环节。随着技术的不断进步&#xff0c;Android签名机制也经历了从v1到v3的演进。本文将带你深入了解Android签名机制的演变过程&#xff0c;揭示每个版本背后的技术细节&#xff0c;并探讨它们对开…

企业如何通过云服务器实现全球连通运营

如果说互联网是一座桥&#xff0c;连接起了全球各地的信息&#xff0c;那云服务器就如同一座高速公路&#xff0c;帮助企业轻松实现跨国家、跨时区的全球运营。 这个听起来像科幻电影的情节其实已经成为了我们现实生活的一部分。现在就来具体看一下如何做到这一点吧。 其一&…

Django开发实战之定制管理后台界面及知识梳理(中)

上一篇文章末尾讲到如何能够展示更多的字段在界面上&#xff0c;那么针对整个界面数据&#xff0c;如果我想按照某一个条件进行筛选&#xff0c;我该怎么做呢&#xff0c;只需要加上下面一行代码 注意&#xff1a;中途只有代码片段&#xff0c;文末有今天涉及的所有代码 1、增…

RuoYi-Vue-Plus (Logback 和 logback-plus.xml 、p6spy)

项目后本地日志 一、logback依赖 打开最外层的 pom.xml,查看 SpringBoot的依赖配置。 <dependencyManagement><dependencies><!-- SpringBoot的依赖配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>s…

视频汇聚管理/安防监控系统EasyCVR如何开启和调用验证码登录接口?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备传统安防视…

项目实施方案:多点异地机动车典型系统试验状态可视监控系统

目录 一、需求分析 1.1项目背景 1.2项目概述 二、系统优势 2.1兼容性能力强 2.2接入协议多样 2.3并发能力强 2.3.1 单平台参数 2.3.2 多平台性能参数 2.4 系统稳定性 三、建设目标 3.1安全性 3.2可扩展性 3.3易用性 3.4兼容性 3.5 响应能力 四、系统整体解决方…

C#窗体程序设计笔记:如何调出控件工具箱,并设置控件的属性

文章目录 调出控件工具箱设置控件属性 调出控件工具箱 使用Visual Studio打开C#解决方案后&#xff0c;初始界面如下图所示&#xff1a; 接着&#xff0c;在上方的菜单栏依次选择“视图”“工具箱”&#xff0c;即可打开工具箱&#xff0c;如下图所示&#xff1a; 设置控件属…

Service Worker的生命周期和全局对象和API

Service Worker的生命周期和全局对象和API 当我们注册了Service Worker后&#xff0c;它会经历生命周期的各个阶段&#xff0c;同时会触发相应的事件。整个生命周期包括了&#xff1a;installing --> installed --> activating --> activated --> redundant。当Se…

vue2人力资源项目6角色管理

elementUi编写表格样式及分页组件 <template><div class"container"><div class"app-container"><!--角色管理内容--><div class"role-operate"><el-button type"primary">添加角色</el-butt…

高级个人主页

高级个人主页 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" name"viewport" content"widthdevice-width, initial-scale1, maximum-scale1, use…

2024年3月 电子学会 青少年等级考试机器人理论真题五级

202403 青少年等级考试机器人理论真题五级 第 1 题 下图程序运行后&#xff0c;串口监视器显示的结果是&#xff1f;&#xff08; &#xff09; A&#xff1a;0 B&#xff1a;1 C&#xff1a;3 D&#xff1a;4 第 2 题 下列选项中&#xff0c;关于74HC595移位寄存器芯片的…

【ARM Cortex-M 系列 2.3 -- Cortex-M7 Debug event 详细介绍】

请阅读【嵌入式开发学习必备专栏】 文章目录 Cortex-M7 Debug eventDebug events Cortex-M7 Debug event 在ARM Cortex-M7架构中&#xff0c;调试事件&#xff08;Debug Event&#xff09;是由于调试原因而触发的事件。一个调试事件会导致以下几种情况之一发生&#xff1a; 进…

2024第16届四川教育后勤装备展6月1日举办 欢迎参观

2024第16届四川教育后勤装备展6月1日举办 欢迎参观 邀请函 主办单位&#xff1a; 中国西部教体融合博览会组委会 承办单位&#xff1a;重庆港华展览有限公司 博览会主题&#xff1a;责任教育 科教兴邦 组委会&#xff1a;交易会159交易会2351交易会9466 展会背景 成都…

matlab使用2-基础绘图

matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点&#xff0c;从0到10&#xff0c;间隔为0.01 y sin(x); % y轴的数据点&#xff0c;是x的正弦…