设计模式6-原型模式
当我们有一个对象时,想基于该对象生成一个一模一样的对象,有人说,那我直接拷贝构造一个不就行了,专门搞个设计模式岂不是脱裤子放屁?确实,比如我有一个Cat c = new Cat;想再造一个直接拷贝构造即可,但是如果我用 Abstruct Animal = new Cat; 我只有一个抽象类的指针却想生成一个一模一样的猫,貌似拷贝构造就解决不了问题了 再举个例子,比如画图工具,一般都会提供右键选中已有图形,复制一份的功能,但是如果这个图形只是一个抽象类的指针,应该如何复制出一个一样的形状? 我们设计一个抽象的类shape,提供一个纯虚函数clone,它的返回类型为shape* ,每个继承它的类,无论是圆形还是方形必须重写该方法,当我们拿到一个shape*指针时,无论它实际是个圆还是个方形,只要调用clone一定可以获取一个一模一样的对象 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960#in...
设计模式5-建造者模式
建造者模式主要为解决一个问题,当构造一个对象本身变得复杂时,如果又有另一个类似的对象需要构造,难道需要程序员自己清楚的记住应该先干嘛后干嘛然后获得一个对象吗?能不能把构造流程标准化?标准化的流程顺带解决了另一个问题,它可以防止未构造完成的”半成品”流入客户手中产生未知后果 比如我们需要建造一座房子,一定是从下往上建造,依次完成地面,墙体,以及屋顶。无论是木屋还是石头屋都要遵守这个流程,先设计一个抽象的Builder类,它有建造地面,墙体,屋顶的方法,并提供一个最后的获取产品的接口build,用WoodHouseBuilder和StoneHouseBuilder来继承它,分别实现建造各个组件的方法,最后我们设计一个director,让他指导Builder将建造流程标准化(先建造地面,然后墙,然后屋顶),最后我们即可从Builder的build接口获取到一个成品房子,绝对不会拿到一个半成品 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535...
设计模式4-抽象工厂
与前面两个工厂不同的是,抽象工厂提供的产品不是同一个类型的东西,而是一系列配套的不同产品。例如一个网站可能会有Light theme和Dark theme,对应不同的皮肤skin,按钮button,搜索栏searchbar。如何在装配时防止出现Light的skin和button但是搭配上了Dark的searchbar,即是抽象工厂要解决的问题 我们定义一个最终产品类叫做page,page里包括了skin,button,searchbar。然后给出Light和Dark分别对这三个组件的实现,设计一个抽象工厂类,实现LightFactory和DarkFactory来装配page并返回指针 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103...
设计模式3-工厂方法
简单工厂模式有个缺点,当我需要添加一件产品时,必须去修改工厂函数,违反了对扩展开放对修改关闭的原则。另外如果产品类型过多的话,工厂函数里if-else/switch-case将会非常长,难以维护,因此工厂方法应运而生。 工厂方法的思想为给定一个抽象工厂类,每件产品单独由一个工厂来生产,这个工厂继承了抽象工厂基类,当我需要添加一件产品时,只需要再增加一个工厂即可,实现了对扩展开放,对修改关闭 下面是一个工厂方法的例子,由简单工厂代码改造而来,我们将工厂设计为抽象类factory,不同型号的产品单独提供一个工厂类继承factory,需要什么型号的产品就造一个对应类型的工厂 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970#include <iostream>enum class model { su7, modelY, M7...
虚拟地址空间划分
以32位linux进程为例 当进程被操作系统加载时,操作系统会给该进程提供一块 0x00000000~0xFFFFFFFF 共4G大小的虚拟内存地址空间 0x00000000~0xFFFFFFFF 0x00000000~0xC0000000 : 用户空间 0x00000000~0x08048000 : 预留空间(不允许访问) .text .rodata : 代码段和只读数据区 .data : 数据段,存储已初始化且不为0的变量 .bss : 未初始化+已初始化为0的变量 .heap : 堆区 共享库 : 加载.so的地方 .stack: 栈区 : 命令行参数和环境变量 0xC0000000~0xFFFFFFFF : 内核空间 12345678910111213141516171819int gdata1 = 10;int gdata2 = 0;int gdata3;static int gdata4 = 10;static int gdata5 = 0;static int gdata6;int main() { int a = 12; in...
设计模式2-简单工厂模式
简单工厂模式一般用来构造一系列相同类型的产品,用基类提供接口,具体产品继承基类,工厂函数根据枚举生成不同产品,并返回基类指针 下面是一个简单工厂模式的例子,我们有一个基类car,car可以派生出小米su7,特斯拉,M7等具体型号的产品,创建一个工厂类factory,我们只需要告诉工厂需要的具体型号,工厂负责生产好产品并返回给我们基类指针 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <iostream>enum class model { su7, modelY, M7};class car {public: virtual void info() = 0; virtual ~car(){};};class MiSu7 : public car{public: void info(...
设计模式1-单例模式
单例模式应该算是最简单的一种设计模式了,只需要提供一个static的getInstance方法,然后将构造函数以及赋值运算符全给删除,即可保证每次通过getInstance获取的是同一个对象。 但实际上,它只是把全局变量包装了一层,就像在花裤衩外套了一层西装,看起来好看点而已。忠告就是不要滥用单例模式,只有确实整个生命周期内只需要一个(例如日志模块)的场景才建议使用,否则单例对象会一直贮存在内存中,即使你已经不需要它 123456789101112131415161718192021222324252627282930313233343536373839#include <iostream>#include <utility>class Singleton {public: static Singleton* getInstance() { static Singleton instance; return &instance; } Singleton(const ...
H264结构详解
frame视频的一张图片就叫一帧,H264分为I帧,P帧,B帧。 slice一个frame可以切成多个slice,slice之间在解码过程中是相对独立的,能够限制产生花屏时的影响范围 NALUNALU = NAL HEADER + NAL Payload(slice data); NAL HEADERNAL HEADER = Forbidden_zero_bit(1bit)必须为0 + nal_ref_idc(2bit)重要程度,越大越重要 + nal_unit_type(5bit)NALU类型[0,31]; nal_unit_type = {6(SEI), 7(SPS), 8(PPS), 5(IDR帧), 1(非IDR帧), 28(FU-A分片)} NAL PayloadSODB编码器原始输出的比特流(非字节对齐) RBSPSODB + 补齐字节,凑齐到8bit整数倍(停止位1 + n个0) EBSPRBSP中的 0x00 00 XX (XX = {00, 01, 02, 03}), 替换为 0x00 00 03 XX NALU交界NAL...
pkg-config
前言pkg-config是一个命令行工具,用于提供库(libraries)的编译和链接信息 用法123pkg-config --list-all #查看所有支持pkg-config的库pkg-config --libs --cflags glib-2.0 # 名字就是本地/usr/lib/x86_64-linux-gnu/pkgconfig/*.pc的前缀 CMake集成pkg-config12345678910# 1. 引入 pkg-config 模块find_package(PkgConfig REQUIRED)# 2. 查找某个库,例如 libcurlpkg_check_modules(CURL REQUIRED libcurl)# 3. 使用查找到的变量target_include_directories(my_app PRIVATE ${CURL_INCLUDE_DIRS})target_link_libraries(my_app ${CURL_LIBRARIES})target_compile_options(my_app P...
ffmpeg SDK学习(4)
从 ffmpeg 接口到 x264 接口libavcodec/libx264.c 中定义了结构体 1234567891011121314151617181920212223242526const FFCodec ff_libx264_encoder = { .p.name = "libx264", CODEC_LONG_NAME("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .p.type = AVMEDIA_TYPE_VIDEO, .p.id = AV_CODEC_ID_H264, .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS | AV_CODEC_...









