12 2019 档案
摘要:界面与逻辑基本程序架构一般包含:—用户界面模块(UI) 接受用户输入及呈现数据—业务逻辑模块(Business Logic) 根据用户需求处理数据 用户界面与业务逻辑如何交互? 基本设计原则功能模块之间需要进行解耦核心思想:强内聚,弱耦合-每个模块应该只实现单一的功能-模块内部的子模块只为整体的单一
阅读全文
摘要:QCalculatorDec.h QCalculatorDec.cpp
阅读全文
摘要:中缀表达式转后缀表达式的过程类似编译过程——四则运算表达式中的括号必须匹配——根据运算符优先级进行转换——转换后的表达式中没有括号——转换后可以顺序的计算出最终结果 这是某位伟人研究出的算法,在这里我们直接拿来用就可以。 转换过程:——当前元素e为数字:输出——当前元素e为运算符:1.与栈顶运算符进
阅读全文
摘要:计算机如何读懂四则运算表达式?9.3 + (3 - -0.11) * 5 后缀表达式人类习惯的数学表达式叫做中缀表达式另外,还有一种将运算符放在数字后面的后缀表达式5 + 3——> 5 3 +1 + 2 * 3 ——> 1 2 3 * +9 + (3 - 1) *5 ——> 9 3 1 - 5* +
阅读全文
摘要:标准库STL Qt VS STL Qt中的字符串类——采用Unicode编码,意味着可以直接支持韩文、日文、中文等等。而STL中的string类不支持Unicode编码,只支持ascII码。——使用隐式共享技术来节省内存和不必要的数据拷贝——跨平台使用,不必考虑字符串的平台兼容性 注意:隐式共享技术
阅读全文
摘要:Qt消息模型Qt封装了具体操作系统的消息机制Qt遵循经典的GUI消息驱动事件模型 如果你只关注两头,即用户做某个操作,那么应用程序中的消息处理函数将被调用。 Qt中如何表示用户消息?用字符串来描述消息Qt中如何映射用户消息到消息处理函数?connectQt中消息映射需要遵循什么规则? 信号与槽Qt中
阅读全文
摘要:计算器界面代码重构什么是软件开发过程中的重构?重构(Refactoring)——以改善代码质量为目的代码重写 使其软件的设计和架构更加合理 提高软件的扩展性和维护性 代码实现与代码重构不同——代码实现 按照设计编程实现,重心在于功能实现——代码重构 以提高代码质量为目的软件架构设计 区别: 代码实现
阅读全文
摘要:QLineEdit组件 QLineEdit用于接受用户输入QLineEdit能够获取用户输入的字符串QLineEdit是功能性组件,需要父组件作为容器QLineEdit能够在父组件中进行定位 设计与实现界面设计——定义组件间的间隔 .Space = 10px——定义按钮组件的大小 .Width =
阅读全文
摘要:坐标系统GUI操作系统都有特定的坐标系统图形界面程序在坐标系统中进行窗口和部件的定位定位类型——顶级窗口部件的定位——窗口内部件的定位——窗口部件的大小设置 Qt使用统一的坐标系统定位窗口部件的位置和大小Qt部件类提供成员函数在坐标系统中进行定位QWidget类提供了窗口部件所需的坐标系统成员函数
阅读全文
摘要:窗口部件和窗口类型并不是Qt中才有的概念,其他的平台中也有类似的概念。 图形用户界面由不同的窗口和窗口组件构成(也就是说窗口和窗口组件是图形用户界面开发中的最小单元)<QtGui>头文件包含窗口组件,对应Qt中的GUI模块Qt以组件对象的方式构建图形用户界面 组件的类型:——容器类(父组件):用于包
阅读全文
摘要:有没有发现,在这个主函数里面没有了消息循环了。消息循环到哪里去了呢? 我们知道,每个GUI应用程序都有消息循环,一般都需要将消息循环while那个函数写到main的最后位置。那既然如此,为了代码复用,我们为什么不把它封装起来呢?因此就有了Application这个应用程序类,接下来首先看一下,App
阅读全文
摘要:GUI程序开发概述 GUI程序开发原理 GetMessage(&msg)将消息队列中的消息取出来,在循环中进行处理。 GUI程序开发的本质
阅读全文
摘要:图形界面应用程序图形界面应用程序的特点(Graphic User Interface)——是一种基于消息驱动模型的可执行程序——程序的执行依赖于用户的交互过程——程序执行过程中实时响应用户操作——一般情况下程序执行后不会主动退出 小结:
阅读全文
摘要:完成DynamicArray类的具体实现 DynamicArray设计要点——类模板 动态确定内部数组空间的大小 实现函数返回数组长度 拷贝构造和赋值操作 DynamicArray类的声明 测试: 代码优化: DynamicArray类中的函数实现存在重复的逻辑,如何进行代码优化? 重复代码逻辑的抽
阅读全文
摘要:问题:长度相同的两个SeqList,插入和删除操作的平均耗时是否相同? 下面的代码正确吗?为什么? 2. 导致上面出现问题的原因就是,拷贝构造函数和赋值操作,因此我们可以这样解决: 对于容器类型的类,可以考虑禁用拷贝构造和赋值操作。 下面的代码正确吗?为什么? 这段程序会崩掉,因为你把线性表当作数组
阅读全文
摘要:创建好的基于顺序存储结构的线性表存在两个方面的问题:1)功能上的问题:数组操作符的重载带来的问题,有可能线性表被无用为数组了,线性表被当做数组来使用了。2)效率方面的问题 本篇博客就要解决功能上的问题。 数组类的开发需要在DTLib中提供安全可靠的原生数组的代替品,原生数组C++是直接支持的,但是原
阅读全文
摘要:DynamicList设计要点——类模板 申请连续空间作为顺序存储空间 动态设置顺序存储空间的大小 保证重置顺序存储空间时的异常安全性 DynamicList设计要点——函数异常安全的概念 不泄露任何资源 不允许破坏数据——函数异常安全的基本保证 如果异常被抛出 对象内的任何成员仍然能保持有效状态
阅读全文
摘要:到目前为止,我们还无法创建一个顺序存储结构线性表的对象出来,为什么呢?顺序存储空间究竟是什么,顺序存储空间的大小是多少? StaticList设计要点——类模板 使用原生数组作为顺序存储空间 使用模板参数决定数组大小 StaticList.h 测试main.cpp 实验二: 这个地方抛出了一个异常,
阅读全文
摘要:完成顺序存储结构线性表的抽象实现 在SeqList中的关键操作都已经实现了,但它还是一个抽象类,为什么呢?顺序存储空间的指定并没有在SeqList中完成,由StaticList和DynamicList这两个子类中完成。 SeqList设计要点——抽象类模板,存储空间的位置和大小由子类完成——实现顺序
阅读全文
摘要:顺序存储的定义线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表中的数据元素。 在C++中的表现是什么样子的呢?可以考虑用一个数组,一个固定大小的数组来作为存储介质存储线性表中的元素。 如何用C++里面的原生数组实现一个线性表。原生数组符合顺序存储的定义 设计思路——可以用一维数组来
阅读全文
摘要:线性表(List)的表现形式——零个或多个数据元素组成的集合——数据元素在位置上是有序排列的——数据元素的个数是有限的——数据元素的类型必须相同 线性表的一些常用操作——将元素插入线性表——将元素从线性表中删除——获取目标位置处元素的值——设置目标位置处元素的值——获取线性表的长度——清空线性表 线
阅读全文
摘要:遵循经典设计准则——DTLib中的所有类位于单一的继承树中 Object这个顶层父类定义了动态内存申请时的行为,当动态内存申请失败时,直接返回空指针,并不会抛出异常。所以说DTLib中的每一个类,在动态内存申请结束时一定要判断是不是空指针 为什么要增加InvalidOperationExceptio
阅读全文
摘要:创建一个可复用的数据结构类库可复用:就是在不同的工程里面可以使用这门课创建的数据结构库,在不同的编译器、不同的工程里使用DTLib都是可以的。当代软件架构实践中的经验——尽量使用单重继承的方式进行系统设计 (单重继承+多接口)——尽量保持系统中只存在单一的继承树 (在当代的软件架构中是如何来保证呢?
阅读全文
摘要:1.Exception.h 中增加ArithmetricException类 2.Exception.h 中增加NullPointerException类 3.Exception.h 中增加IndexOutOfBoundsException类 4.Exception.h 中增加NoEnoughMem
阅读全文
摘要:异常类构建异常的类型可以是自定义类类型对于类类型异常的匹配依旧是从上到下严格的匹配赋值兼容性原则在异常匹配中依然适用一般而言-匹配子类异常的catch放在上部-匹配父类异常的catch放在下部 现代C++库必然包含充要的异常类族异常类是数据结构类所依赖的基础设施 Exception是一个抽象类,不能
阅读全文
摘要:智能指针实际上就是通过模板技术实现的一个类 内存泄露(臭名昭著的Bug)——在软件开发和测试阶段都不容易被发现-动态申请堆空间,用完后不归还-C++语言中没有垃圾回收的机制-指针无法控制所指堆空间的生命周期 当代C++软件平台中的智能指针-指针生命周期结束时主动释放堆空间-一片堆空间最多只能由一个指
阅读全文
摘要:数据结构课程的特点-专注于数据元素之间的关系-专注于特定结构之上的算法 数据结构课程并不关注数据元素的具体类型。 泛型编程的概念-不考虑具体数据类型的编程方式对于Swap函数可以考虑下面的泛型写法 void Swap(T& a, T& b) { T t = a; a = b; b = t; } Sw
阅读全文
摘要:1.编写一个程序判断一个变量是不是指针? 拾遗-C++中仍然支持C语言中的可变参数函数-C++编译器的匹配调用优先级1.重载函数2.函数模板3.变参函数 #include <iostream> #include <string> using namespace std; class Test { p
阅读全文
摘要:C++中如何得到动态类型? #include <iostream> #include <string> using namespace std; class Base { public: virtual string type() { return "Base"; } }; class Derive
阅读全文
摘要:C++内置了异常处理的语法元素try... catch ...-try语句处理正常代码逻辑-catch语句处理异常情况-try语句中的异常由对应的catch语句处理 C++通过throw语句抛出异常信息 C++异常处理分析-throw抛出的异常必须被catch处理 当前函数能够处理异常,程序继续往下
阅读全文
摘要:异常的概念-程序在运行过程中可能产生异常-异常(Exception)与Bug的区别 异常是程序运行时可预料的执行分支 Bug是程序中的错误,是不被预期的运行方式 异常(Exception)和Bug的对比-异常 运行时产生除0的情况 需要打开的外部文件不存在 数组访问时越界-Bug 使用野指针 堆数组
阅读全文
摘要:单例模式需求的提出在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在(Single Instance)如何定义一个类,使得这个类最多只能创建一个对象?明确创建一个对象,必然会调用构造函数。要控制类的对象数目,必须对外隐藏构造函数 思路:-将构造函数的访问属性设置为private-定义in
阅读全文
摘要:小结:智能指针是C++中自动内存管理的主要手段智能指针在各种平台上都有不同的表现形式智能指针能够尽可能的避开内存相关的问题STL和Qt中都提供了对智能指针的支持
阅读全文
摘要:Qt中的智能指针-QPointer .当其指向的对象被销毁时,它会被自动置空 .析构时不会自动销毁所指向的对象-QSharedPointer .引用计数型智能指针 .可以被自由的拷贝和赋值 .当引用计数为0时才删除指向的对象 析构函数没有被调用,意味着pt这个智能指针对象,它在生命周期结束时并没有同
阅读全文
摘要:智能指针类模板智能指针本质上就是一个对象,它可以像原生指针那样来使用。 智能指针的意义-现代C++开发库中最重要的类模板之一-C++中自动内存管理的主要手段-能够在很大程度上避开内存相关的问题 1.内存泄露,在测试阶段很难发现。造成的原因就是申请堆空间中的内存,忘记释放。 2.多次指针释放:一个指针
阅读全文
摘要:优化之前的IntArray类 小结:模板参数可以是数值型参数数值型模板参数必须在编译期间唯一确定数组类模板是基于数值型模板参数实现的数组类模板是简易的线性表数据结构
阅读全文
摘要:预备知识模板参数可以是数值型参数(非类型参数)template<typename T, int N>void func(){ T a[N]; //使用模板参数定义局部数组}func<double, 10>(); 数值型模板参数的限制-变量不能作为模板参数(变量是不能在编译期就唯一确定的)-浮点数不能
阅读全文
摘要:多参数类模板类模板可以定义任意多个不同的类型参数template <typename T1, typename T2>class Test{public: void add(T1 a, T2 b);}; 使用上述的类模板: Test<int ,float> t; 类模板可以被特化:即特殊化-指定类模
阅读全文
摘要:类模板的概念和意义类模板一些类主要用于存储和组织数据元素类中数据组织的方式和数据元素的具体类型无关如:数组类,链表类,stack类,Queue类等C++中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能 C++中的类模板-以相同的方式处理不同的类型-在类声明前使
阅读全文
摘要:函数模板深入理解-编译器从函数模板通过具体类型产生不同的函数-编译器会对函数模板进行两次编译 对模板代码本身进行编译 对参数替换后的代码进行编译 注意事项:-函数模板本身不允许隐式类型转换 自动推导类型时,必须严格匹配 显示类型指定时,能够进行隐式类型转换 编程实验函数模板本质分析 多参数函数模板函
阅读全文
摘要:发散性问题 C++中有几种交换变量的方法? 定义宏代码块 VS 定义函数 编程实验 利用定义宏代码块的方法看上去很完美,但是宏是预处理器处理的程序单元,后续出场的编译器根本不知道宏的存在,因此不推荐用宏来完成类似函数的功能。因为不安全。 直接定义函数 定义宏代码块-优点:代码复用,适合所有的类型-缺
阅读全文
摘要:dynamic_cast是与继承相关的类型转换关键字dynamic_cast要求相关的类中必须有虚函数用于直接或者间接继承关系的指针(引用)之间-指针: 转换成功:得到目标类型的指针 转换失败:得到一个空指针 -引用: 转换成功:得到目标类型的引用 转换失败:得到一个异常操作信息 编译器会检查dyn
阅读全文
摘要:构造函数是否可以成为虚函数?构造函数不能成为虚函数-C++中的多态是由指向虚函数表的指针来完成的,那么指向虚函数表的指针是由编译器创建的,同时也是由编译器进行初始化。那什么时候对虚函数表指针进行初始化呢?-在构造函数执行结束后,虚函数表指针才会正确的初始化 析构函数是否可以成为虚函数?-建议在设计类
阅读全文
摘要:new和malloc的区别是什么?-new关键字是C++的一部分,在所有的C++编译器中都被支持-malloc是由C库提供的函数,在某些系统开发中是不能调用的-new以具体类型为单位进行内存分配-malloc以字节为单文进行内存分配-new在申请内存空间时可以进行初始化,它会触发构造函数的调用-ma
阅读全文
摘要:工程开发中的多重继承方式:(这是面向对象理论中所推荐的方式)单继承某个类 + 实现(多个)接口 在父类中添加一个成员函数,用于解决在多继承的情况下指向同一个对象的多个指针它们的值不一样。定义接口class Interface1、class Interface2这样的方式是工程中常用的一种解决方案。但
阅读全文
摘要:多重继承的问题三:多重继承可能产生多个虚函数表 sizeof(d) = 8 相关的三个类中都没有定义成员变量,那这8个字节是从哪来的,谁占用的?虚函数表指针 在Derived这个类中有两个成员,这两个成员都是虚函数表指针。在创建对象的时候,这两个成员会指向不同的虚函数表 需要进行强制类型转换时,C+
阅读全文
摘要:问题:C++中是否允许一个类继承自多个父类呢?答案是肯定的,这种现象就是多重继承多重继承是C++中一个特有的特性,因为在其他的程序设计语言里面,如C#、java等语言只支持单重继承 C++支持编写多重继承的代码-一个子类可以拥有多个父类-子类拥有所有父类的成员变量-子类继承所有父类的成员函数-子类对
阅读全文
摘要:什么是抽象类面向对象中的抽象概念在进行面向对象分析时,会发现一些抽象的概念图形的面积如何计算? 在现实中需要知道具体的图形类型才能求面积,所以对概念上的图形求面积是没有意义的 Shape只是一个概念上的类型,没有具体的对象。 面向对象中的抽象类-可用于表示现实世界中的抽象概念-是一种只能定义类型,而
阅读全文
摘要:多态的本质分析 用C写面向对象,用C实现多态 继承的本质就是父子间成员变量的叠加C++中的多态是通过虚函数表实现的虚函数表是由编译器自动生成与维护的虚函数的调用效率低于普通成员函数
阅读全文
摘要:在C++编译器内部类可以理解为结构体子类是由父类成员叠加子类新成员得到的class Derived : public Demo{ int mk;} C++多态的实现原理-当类中声明虚函数时,编译器会在类中生成一个虚函数表-虚函数表是一个存储成员函数地址的数据结构-虚函数表是由编译器自动生成与维护的-
阅读全文
摘要:类中的成员函数位于代码段中调用成员函数时对象地址作为参数隐式传递成员函数通过对象地址访问成员变量C++语法规则隐藏了对象地址的传递过程 d.getI()d对象的地址被传到了getI这个函数的内部,但是传递过程在C++代码中是看不到的。深度挖掘的就是编译器背后的故事,此时就需要用到C语言了,用C语言实
阅读全文
摘要:C++对象模型,其实就是C++中的对象在内存中是如何排布的。C++中的对象包含了成员变量和成员函数,其实就是研究C++中的类对象它的成员变量和成员函数在内存中是如何排布的。 回归本质class 是一种特殊的struct(之所以特殊,是因为它们的默认访问级别不一样)-在内存中class依旧可以看作变量
阅读全文
摘要:函数重写回顾父类中被重写的函数依然会继承给子类子类中重写的函数将覆盖父类中的函数通过作用域分辨符(::)可以访问到父类中的函数Child c;Parent* p = &c; c.Parent::print(); //从父类中继承c.print(); //在子类中重写 p->print(); //父类
阅读全文
浙公网安备 33010602011771号