设计模式及C++实现

  • 类设计的原则
    • 1. 开闭原则
    • 2. 里氏替换原则
    • 3. 依赖倒置原则
    • 4. 单一职责原则
    • 5. 接口隔离原则
    • 6. 迪米特法则
    • 7. 合成复用原则
  • 类之间的关系
  • 创建型模式
    • 1. 工厂模式
    • 2. 单例模式
    • 3. 建造者模式
    • 4. 原型模式
  • 结构型模式
    • 1. 外观模式
    • 2. 组合模式
    • 3. 适配器模式
    • 4. 代理模式
    • 5. 桥接模式
    • 6. 装饰模式
    • 7. 享元模式
  • 行为型模式
    • 1. 观察者模式
    • 2. 命令模式
    • 3. 策略模式
    • 4. 状态模式
    • 5. 中介者模式
    • 6. 迭代器模式
    • 7. 职责链模式
    • 8. 模板方法模式
    • 9. 备忘录模式
    • 10. 解释器模式
    • 11. 访问者模式

类设计的原则

1. 开闭原则

  • 含义: 软件实体对扩展开放,对修改关闭
  • 实现: 具体类实现抽象类

2. 里氏替换原则

  • 含义: 所有引用基类的地方都可以透明的使用其子类,即父类的对象均可用子类对象替代,不会出现任何错误或异常,反过来却不行
  • 实现:
  1. 子类重写父类的抽象方法
  2. 子类增加特有的方法,不修改父类已实现的方法
  • 最佳实践:
  1. 父类定义为纯接口,不能实例化
  2. 父类使用纯虚函数定义所有子类的公有接口,规范子类的API
  3. 子类特化的实现在父类中定义为纯虚函数
  4. 子类共享的实现在父类中实现
  5. 父类中public只包含接口(用户确实需要调用的方法),private只用于类内部调用
    可适当使用protected以保证子类对父类数据成员或方法的访问

3. 依赖倒置原则

  • 含义: 面向接口编程,而非面向实现编程.高层模块不应该依赖底层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象

4. 单一职责原则

5. 接口隔离原则

  • 含义: 为各个类建立他们需要的专用接口,而不要试图建立一个很庞大的接口供所有依赖它的类去调用
  • 实现: 具体类对多个细粒度接口的继承
  • 优点:
  1. 将臃肿庞大的接口分解为多个粒度较小的接口,可提高系统的灵活性和可维护性
  2. 提高系统的内聚性,减少对外交互,降低了系统的耦合性
  3. 便于体现出对象的层次,通过接口的继承,实现对总接口的定义

6. 迪米特法则

  • 定义: 如果来年各个软件实体无需直接通信,就不应当发生直接的相互调用,可通过
     第三方转发该调用
  • 实现: 依赖者只依赖应该依赖的对象;被依赖者只暴露应该暴露的方法
  1. 类划分时,创建弱耦合的类(尽量不用泛化关系,多用关联关系,多用依赖关系)
  2. 保持类内数据成员和方法的最低访问权限
  3. 不暴露类的属性成员,提供访问方法封装(set(), get())
  4. 慎用序列化(Serialize)
  5. 优先创建不可变类(类的数据成员在对象实例化后就不再改变)
  • 优点: 降低类之间的耦合,提高模块的相对独立性

7. 合成复用原则

  • 定义: 处理类之间的依赖,尽量使用组合关系,不用继承关系

类之间的关系

  1. 泛化: is-a, 具体类到具体类的继承,如小汽车类和SUV,强耦合,因为实现了父类,父类改变
    子类也会受到影响
  2. 实现: is-a, 具体类对抽象类的继承,如车类和小汽车类,接口,方便扩展
  3. 聚合: has-a, 部分离开了整体依然存在,如大雁群和单个大雁,成员变量(硬编码)
  4. 组合: has-a, 构成关系,如小汽车和零件,成员变量(硬编码)
  5. 依赖: 临时性的关联,常通过局部变量,成员函数的参数,静态函数调用,返回值等完成
  6. 关联: 一个对象需要知道另一个对象的变化,表示为使用时的调用

创建型模式

1. 工厂模式

1.1 解决的问题:
对象的创建和对象的使用之间的耦合,在某些场景下编程不便:

  • 对象的消费者不关心对象的初始化方式,只想使用它, 如提供日志功能的类,日志类的实现差异导致了其初始化的差异, 使用者只关心不同日志类提供的类似的接口,如LOG,WARN,ERROR.
  • 对象的初始化过于复杂,需要配置大量的参数,最好与其使用独立开来

1.2 解决方法:

  1. 使用工厂类专门负责对象产品的生产;
  2. 产品对象使用抽象产品类and具体产品类,
    抽象产品类的功能:
    a) 提供产品功能的统一函数接口
    b) 用于工厂函数的返回类型,统一产品返回类型
    具体产品类的功能:
    a) 实现具体产品功能
    b) 使用多态机制中的指针返回具体产品类对象

为什么函数中创建对象返回时必须使用普通指针?

  1. 函数返回对象可以拷贝(值返回)or不拷贝
  2. 多态机制排除值返回,因为值无法用到多态
  3. 不拷贝可使用引用,指针 or 智能指针
  4. 引用只能使用local static对象,该对象生命周期无法控制,排除
  5. 指针只能使用new在堆上创建,合适
  6. 对象的生命周期(用多久)应当由使用者确定,而非工厂类决定,排除智能指针

1.3. 分类:
1) 简单工厂模式
需求: 根据传入参数(可通过配置文件配置)的不同返回不同的具体产品;
方法: 工厂类实现工厂函数,传参返回产品子类
缺点: 违反"开闭原则",增加新的产品需要修改工厂类
适用场景: 产品的数目较少
2) 工厂模式
需求: 解决"简单工厂模式增加新的产品需要修改工厂类"的问题
方法: 定义抽象工厂类,创建产品由工厂子类完成,每个子类生产一种产品
缺点: 当产品数较多时,需要额外增加的工厂子类太多
适用场景: 产品的数目较多,且为单一类别
3) 抽象工厂模式
需求: 一个工厂需要有能力创建多个产品类别的产品,形成该工厂的产品族
方法: 增加工厂类的成员函数,生产多个类别的产品
缺点: 与工厂模式类似
适用场景: 确实需要工厂生产多个产品类;消费者一次使用一个产品族

2. 单例模式

2.1 解决的问题:
系统中只允许存在类的一个实例,即只能创建一次,其他用户(.cc)均能使用

2.2 解决方法:

产品类同时担当工厂类的角色,创建自身的实例,且提供全局访问接口

  1. 私有化构造函数(不允许用户自行创建)
  2. 使用静态成员变量和静态成员函数创建类的实例(全局访问接口)
  3. 禁用拷贝语义(避免对象的拷贝)

2.3 缺点: 违反"单一职责原则",对象的创建和业务逻辑(产品类)耦合

2.4 应用场景: 如全局序列号生成器

3. 建造者模式

3.1 解决的问题
对象的创建过程较为复杂,各个属性之间有依赖关系,一个属性的初始化依赖于另一个
属性的状态

3.2 解决方法
设计Builder抽象类,提供建造对象的步骤step1(), step2(), …,待建造的对象作为
数据成员,提供外部接口GetObject()执行步骤,返回建造好的对象

4. 原型模式

4.1 解决的问题
想获得一个对象运行过程中的拷贝(执行过程中其属性可能被自己或其他类对象改变),
同时不想知道该对象的具体类

4.2 解决方法
设计Clonable接口,提供Clone()方法,具体类重写该方法,实现深拷贝

4.3 与拷贝的关系
1) 为什么不用拷贝构造函数?
拷贝构造函数只能返回当前具体类类型,我们不关心具体类的类型,只是想获得其一份拷贝,因此通过多态机制实现,返回的类型为Clonable*即可
2) 为什么需要深拷贝?
对对象类型一般通过指针访问,节省开销,但是默认的 = 操作只是浅拷贝,容易造成
指针悬挂; 对内置类型,如int, double, char的浅拷贝没问题,对类类型就不行了

结构型模式

1. 外观模式

1.1 解决的问题:
客户端与依赖与多个子系统的交互,接口比较多,调用不够方便

1.2 解决方法:
1) 引入客户端和多个子系统中间的第三者:外观类,该类封装多个子系统的接口,向客户端
提供简便易用的接口;
2) 子系统的对象定义为外观类的数据成员;
3) 外观类的成员函数调用多个子系统的接口;
4) 一般将外观类定义为单例类,因为一种外观只需要一个对象,但子系统可以有多个外观类;

1.3 缺点:
1) 不能限制客户端对子系统的访问
2) 如不增加抽象外观类,违反"开闭原则"

1.4 应用场景:
1) 为多个复杂子系统提供一个简单接口
2) 层次化结构中,层与层之间不直接通信,使用外观类作为每一层的入口

2. 组合模式

2.1 解决的问题:
整体和部分同时出现的树形结构,如文件结构:文件夹下包含文件和文件夹,在定义
文件夹类(整体)时,需要针对文件和子文件夹(部分)分别定义集合,并在各自的
对象集合上操作,代码冗余

2.2 解决方法:
取整体和部分的共同点设计抽象基类,部分形成的集合只需要包含基类类型即可

2.3 缺点:
1) 客户端难以理清类之间的层次关系
2) 增加新构件时难以对容器中的构件类型进行限制

2.4 应用场景:
1) 在有整体和部分的层次结构中,客户端希望忽略整体和部分的差异,使用一致的
  方式对待他们
2) 使用类表示树形结构(vector数据成员表示孩子节点列表)
3) 一个系统中可分离出叶子对象和容器对象,他们的类型不固定,需要增加一些新的
 类型

2.5 分类:

  1. 透明组合模式
    抽象类的接口覆盖了所有构件的接口,即使有些构件用不到部分接口(如文件类不需要像
    文件夹类那样有Add(), Remove()接口),文件类对这些接口实现时返回错误或抛异常.
    优点: 构件接口一致,用户只需要了解抽象类的接口

  2. 安全组合模式
    抽象类的接口是所有构件接口的交集,构件分别在自己的类中定义特有的接口
    优点: 不会给某些构件定义不必要的接口,用户使用更加安全

3. 适配器模式

3.1 解决的问题:
调用者期待的类接口和已有的类接口不一致,需要做转换

3.2 解决方法
引入适配器类,适配器内部调用已有的类原有的接口来实现Target定义的接口

3.3 分类:

  1. 类结构型适配器: 同时继承Target和Adaptee
    优点: 可方便改动Adaptee的函数接口,更灵活

  2. 对象结构型适配器: 只继承Target,Adaptee作为成员变量
    优点: 可组合多个Adaptee

4. 代理模式

4.1 解决的问题:
用户不想或不能直接使用一个对象时,通过第三方的代理实现间接调用,比如RPC

4.2 解决方法:
设计中间类Proxy,与被代理类RealSubject共享抽象类接口Subject,由代理类创建RealSubject对象

4.3 应用场景
1) 远程代理: 为不在同一地址空间的对象提供一个本地的代理对象,可位于同一主机或不同主机
2) 虚拟代理: 需要创建一个资源消耗较大的对象时,先创建一个消耗较小的对象表示,
真实对象真正被使用时才被创建
3) 保护代理: 控制对象的访问权限,给不同的用户不同级别的访问权限
4) 缓冲代理: 为目标操作的结果提供临时的存储空间,以便多个客户端可共享这些结果
5) 防火墙代理: 保护目标不被恶意用户接近
6) 同步化代理: 使几个用户同时使用一个对象而不冲突
7) 智能引用代理: 一个对象被引用时,提供一些额外的操作,如将此对象被引用的次数记录下来

4.4 缺点
该模式为静态代理,一个具体类对应一个代理类,当具体类较多时冗余代码较多.
解决: 动态代理,如Java Spring AOP

5. 桥接模式

5.1 解决的问题:
一个系统由两个独立的部分组成,这两个部分之间通过组合可形成满足要求的扩展类

5.2 解决方法:
设计两个抽象类,Abstract和Implementor,两者之间通过对象结构模式形成关联关系,
两者的具体实现类分别对各自的抽象类实现,互不影响

6. 装饰模式

6.1 解决的问题:
在不改变原有类的基础上,给对象增加新的属性而保持原有的调用接口不变

6.2 解决方法
引入Decorator装饰器抽象类,可扩展成不同的具体装饰类.
Decorator类与原有类的函数接口一致,使用抽象类Component显式表示该接口的一致性.
Component对象作为Decorator类的一个数据成员

6.3 优点
轻量化的类扩展

7. 享元模式

7.1 解决的问题
系统中对象的数目太多,降低运行速率

7.2 解决方法
1) 将不同的对象抽象出公共的属性,称为内部状态,特定属性为外部状态
2) 内部状态作为数据成员构造共享的对象,外部状态由参数传入来处理
3) 由简单工厂方法创建共享的对象,使用池技术(map),若已存在,直接取出,否则创建一个加进池中, 将共享对象类设为单例类

7.3 适用场景
实在有必要优化因对象过多导致的运行速率大幅下降的情况,因为享元模式切分对象的属性,
理解起来比较困难

行为型模式

1. 观察者模式

1.1 解决的问题
发布-订阅模式,模型-视图模式,如MVC模式

1.2 解决方法
Publisher类持有Subscriber对象的集合,对所有订阅者的通知通过遍历该集合调用订阅者的
Update()方法,该方法通过Publisher的get_state()方法获取Publisher对象的状态
Subscriber类持有Subscriber对象,创建时自动注册(初始化Subscriber对象并调用Publisher
的Attach()方法),对象销毁时自动退出订阅(在析构函数中调用Publisher的Detatch()方法)

1.3 适用场景
一对多的对象交互场景

2. 命令模式

2.1 解决的问题
1) 不希望调用者和接受者静态绑定,希望在使用时才指定接收者和具体的命令
2) 命令为批处理模式,而非交互模式,即每次执行都是从接收者的初始状态开始,不存储接受者
  的内部状态
3) 只关心命令的发出,而不管命令的具体执行(遥控器,点菜)

2.2 解决方法
定义Receiver类,AbstractCommand, ConcreteCommand, Invoker类
Receiver: On(), Off()等命令的执行方法
AbstractCommand: Execute()接口, 关联Receiver对象
ConcreteCommand: Execute()覆盖,该方法内只调用一个Receiver对象的执行方法
Invoker: Call()方法,给调用者使用,关联Command对象(单命令)or Command对象的集合(批处理命令),调用其Execute()方法

2.3 优点
1) 实现了命令的接收者,具体命令,命令的调用者之间的解耦,彼此可以独立变化,使用时再动态绑定(可看出对象结构的设计模式的优越性)
2) 可方便的执行或回滚命令,实现了事务机制(回滚通过重新执行一遍命令实现)
3) 方便的执行批处理命令,与组合模式结合可实现递归批处理(广度优先遍历)

3. 策略模式

3.1 解决的问题
同一种解决方案有不同的策略,区别只在于具体实现方法的不同,如排序算法可以选择快速排序,选择排序等,如果将所有算法硬编码进一个类的不同方法中,违反"开闭原则"

3.2 解决方法
定义Context类,Policy类, ConcretePolicy类
Context: Policy数据成员,Run() -> Policy.Execute()
Policy: 定义Execute()接口
ConcretePolicy: 实现Execute()接口

4. 状态模式

4.1 解决的问题
具有状态转移的系统,将状态和行为解耦,用户只需要调用行为接口,状态转移对用户透明

4.2 解决方法
定义Context, State, ConcreteState类
Context: State类对象作为数据成员, Action()为指定行为接口, set_state()改变State
State: 抽象状态类ConcreteState: OnAction()方法,内部创建转移后的状态类对象,并调用set_state()使用该对象改变Context的状态, 由于状态类对象只需要一个,因此将ConcreteState类定义为单例类

4.3 缺点
不符合开闭原则,修改状态转移图需要修改代码

5. 中介者模式

5.1 解决的问题
系统中存在网状的对象交互关系,引入中介者负责控制转发,对象只负责业务部分,将网状结构改为星形结构,可减小对象之间复杂的耦合

5.2 解决方法
引入中介者Mediator,创建对象时将对象注册进中介者持有的交互对象集合,并在该对象中注册中介者;
对象交互通过中介者的转发完成

6. 迭代器模式

6.1 解决的问题
对于不同容器类型返回的集合,希望通过相同的方式对其遍历,使得对数据的访问和数据的存储之间解耦

6.2 解决方法
定义Aggregate类封装具体的容器类型,提供GetSize(), GetItem()方法,并提供GetIterator接口返回该容器类的迭代器;
定义Itaraor类提供迭代器接口用于遍历,包括Next(), IsLast(), GetItem()方法用于顺序遍历,逆序遍历类似

7. 职责链模式

7.1 解决的问题
1) 同一个请求可以由多个角色处理,每个角色的职责权限不同,请求满足特定条件才能被一个角色处理;
2) 该请求的发出者不关心具体那个角色来处理请求
3) 请求要么被当前角色处理,要么被递交给后边的角色,要么没有任何角色来处理

** 7.2 解决方法**
1) 设计抽象类Handler,提供两个接口: set_successor()和HandleRenquest(), set_successor()用于调用者
动态设定该角色的后继角色,HandleRequest()用于实现该角色的职责权限(if-else来判断),若不在权限
范围内,交给后继角色来处理
2) 不同的角色之间的链式结构由调用者自行决定,请求只需要交给链中的第一个角色的HandleRequest()方法

8. 模板方法模式

8.1 解决的问题
一个复杂的算法由若干步流程组成,希望该算法的实现和该算法的调用解耦

8.2 解决方法
1) 定义模板方法类TemplateProcess,提供TemplateMethod()方法,该方法依次调用每步流程
2) 在具体类ConcreteProcessA中覆盖TemplateProcess中的流程方法Step1(), Step2(), …可选择性覆盖

9. 备忘录模式

9.1 解决的问题
希望某一操作支持撤销和恢复,如数据库的备份和恢复,文件版本管理,悔棋

9.2 解决方法
1) 设计Memorandum类,用于外部存储数据(struct)
2) 设计Originator类,持有操作中的数据,负责执行操作,操作中数据的向外暂存(新建Memorandum对象)和恢复(从
Memorandum对象中恢复)
3) 设计CareTaker类,持有Memorandum类对象的列表和index,用于在外部记录历史操作和当前所在步
与Play()对应的操作是Add()或Set(),负责写列表,前者用于新执行一步操作,后者用于撤销后执行一步操作
与Undo()和Redo()对应的操作时GetMemory(),负责读列表
4) 设计Action类,有Play(), Undo(), Redo()操作,持有CareTaker数据成员
Play(): 调用Originator对象执行操作,创建Memorandum对象Add或Set进CareTaker对象的列表,index+1
Undo(): 调用CaraTaker对象GetMemory()然后恢复到Originator对象中,index-1,调用Originator对象执行操作
Redo(): 调用CareTaker对象GetMemory()然后恢复到Originator对象中,index+1,调用Originator对象执行操作
Redo只能位于Undo后,因此设计状态数据成员state_,执行三种操作后改变状态

** 9.3 优缺点**
优点: 将单步原生执行器,备忘数据存储类,历史记录存储类和对用户的执行接口分离开,职责清晰
缺点: 历史记录只增不减,每次执行都需要拷贝进外部存储对象中一次,空间开销大

10. 解释器模式

10.1 解决的问题&解决办法
模仿编译器使用类表示句法规则,对句子做解释,由于使用场景较少,故暂时略过

11. 访问者模式

11.1 解决的问题
类对象存储的数据几乎不变,但却需要提供多种多样的访问方式,比如超市中存储的商品,顾客访问时关注其质量,性价比,售货员关注其售卖数量和单价.这里的访问指"获取数据并处理"

11.2 解决方法
1) 将对象数据的存储和对对象的访问解耦.
2) 定义 Visitor抽象类,对每种具体的元素提供一个访问接口Visit(ElemA); Visit(ElemB);
3) 定义 Element抽象类,提供Accept接口,实现的具体类ElementA, ElementB内部调用visitor.Visit(this)方法
4) 定义 ElemSet类,以Element类对象的集合为数据成员,提供Add(), Remove()接口,并提供Accept()接口
  遍历其中的每个Element元素,调用该元素的Accept()方法

11.3 优缺点
1) 方便增加新的访问类,直接继承抽象类Visitor即可
2) Visitor对元素的具体类编程,而非对抽象类编程,违反"依赖倒置原则"

11.4 扩展
1) 与迭代器模式配合使用,在ElemSet类中提供迭代器接口
2) 与组合模式配合使用,在ElemSet类中将具体元素和具体元素的集合同等看待
参考文献:
看懂UML类图和时序图 — Graphic Design Patterns.
设计模式-工厂模式-场景以及优缺点-目的就是应对变化 (国江面试回答的) - aspirant - 博客园.
设计模式 | 组合模式及典型应用_Java_小旋锋 的博客-CSDN博客.
深入理解享元模式_Java_Rico’s Blogs-CSDN博客.
深入理解设计模式(12):职责链模式 - 一指流砂~ - 博客园.
设计模式 | 备忘录模式及典型应用_Java_小旋锋 的博客-CSDN博客.
访问者模式(Visitor模式)详解.
里氏替换原则 - 简书.
UML时序图(Sequence Diagram)学习笔记_Java_fly_zxy的专栏-CSDN博客.
EA&UML日拱一卒–序列图(Sequence Diagram)::同步/异步_Java_面向对象思考-CSDN博客.
设计模式中的原型模式和C++的拷贝构造函数有什么区别?-CSDN论坛.
C++ 原型模式_C/C++_青春不老,奋斗不止!-CSDN博客.
设计模式之原型模式(c++) - 小金乌会发光-Z&M - 博客园.
设计模式 | 建造者模式及典型应用_Java_小旋锋 的博客-CSDN博客.

设计模式及C++实现相关推荐

  1. 【Design pattern】设计模式思路总结(一)

    看了一周的设计模式,跟着小菜的思路走! 从简单工厂过渡策略,后面看的这几个模式都是在单一职责,开放--封闭原则,依赖倒转原则下不断的改进,采用模式写出的代码更容易扩展,维护! 比较容易懂. 装饰模式: ...

  2. GOF23设计模式(结构型模式)代理模式~

    代理模式应用场景十分广泛,随便一个框架都会用到,因此学好代理模式对后续框架学习是最基本的要素!!今天我们就来讲讲代理模式! 目录 1.简介 1. 核心作用 2. 角色分析 2. 应用场景 4. 分类 ...

  3. GOF23设计模式(创建型模式)工厂模式

    目录: 一:工厂模式的核心本质 二:关于面向对象的六大基本原则 三:工厂模式的三大类详解(代码示例,详细分析) 首先,上咱本GOF23所有工厂模式的分类表格!!! 创建型模式 单例模式.工厂模式.抽象 ...

  4. GOF23设计模式(创建型模式)单例模式

    目录: 一:单例模式的核心作用.常见应用场景 二:五种单例模式及其实现 三:关于反射和反序列化破解单例模式的漏洞,以及相应的解决方案 四:测试五种单例模式的效率 一:核心作用及常见应用场景: 核心作用 ...

  5. Python七大原则,24种设计模式

    七大设计原则: 1.单一职责原则[SINGLE RESPONSIBILITY PRINCIPLE]:一个类负责一项职责.  2.里氏替换原则[LISKOV SUBSTITUTION PRINCIPLE ...

  6. Java设计模式:单例模式

    学而时习,稳固而之心, 好久没有复习java的知识了,今天有空温习了单例模式,这里记录一下 单例模式是常见的设计模式的一种,其特点就是 指一个类只有一个实例,且该类能自行创建这个实例  , 保证一个类 ...

  7. 设计模式中的六大基本原则

    软件设计中的基本共识: 1,高内聚,低耦合:如果想使软件系统架构稳定,那么我们期望软件的各模块内元素结合的紧密,而模块之间的耦合度(关联性)越低越好.高内聚不仅体现在模块上,单独的类或方法也应该是内聚 ...

  8. JS中的7种设计模式

    第九章Refactoring to OOP Patterns 重构为OOP模式 7种设计模式: 1,模版方法模式(template method) 2,策略模式(strategy) 3,状态模式(st ...

  9. 设计模式之创建型汇总

    设计模式 创建型 工厂方法模式 定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行 使用场景: 创建对象需要大量重复的代码 客户端(应用层)不依 ...

  10. [Python设计模式] 第21章 计划生育——单例模式

    github地址:https://github.com/cheesezh/python_design_patterns 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式 ...

最新文章

  1. html表单的常用属性有哪些,整理HTML5中表单的常用属性及新属性
  2. querystring java_java – 自定义枚举的QueryStringBindable
  3. ubuntu系统靠谱的清理内存的方法(can not allocate memory 问题)
  4. html缩略文本,列表中展示富文本的缩略内容
  5. rw1601可以用C语言写程序吗,用8051+1601LCD设计的整型计算器讲解.doc
  6. 将rm -f or -rf 删除命令改为放入回收站,并可通过命令将其撤回
  7. 【转】php json_encode中文为空的解决办法
  8. Centos8 安装 mariadb 最新版 10.5.x
  9. 《博弈论与生活》思维导图
  10. linux mud 游戏,一笑天涯MUD游戏
  11. 游戏中的物品管理系统
  12. 华为薪酬体系的整体框架
  13. c++识别图片身份证号码
  14. 泰坦尼克号沉没之谜,用数据还原真相——Titanic获救率分析(用pyecharts)
  15. “科目四”竟是民间杜撰出来的?
  16. GPLT PAT 编程练习
  17. 计算机毕业学游戏设计师,学游戏设计有前途吗
  18. 通信中间件DDS介绍(一)
  19. Mock模拟数据的使用
  20. 中文编程软件 - 习语言安装与使用入门

热门文章

  1. 投诉建议html界面,投诉_1.html
  2. 经典金融工程讲座-郑振龙教授在西南财大的精彩演讲
  3. java编译安卓APP的步骤_android编译全过程
  4. 清明扫墓一定要知道的常识
  5. Oracle日志详解
  6. 软件开发中的上游和下游
  7. Tomcat启动闪退的原因和解决方法
  8. 原来安装系统如此简单!强烈推荐这样制作Linux系统启动u盘(收藏干货)
  9. ubuntu14.04显卡驱动问题(amd5600k集显7650d)
  10. 分布式日志GrayLog使用