设计模式:简单工厂模式、工厂方法模式、抽象工厂模式

简单工厂模式、工厂方法模式、抽象工厂模式

  • 1. 为什么需要工厂模式?
  • 2. 简单工厂模式
    • 2.1. 定义
    • 2.2. 代码实现
    • 2.3. 优点
    • 2.4. 缺点
    • 2.5. 适用场景
  • 3. 工厂方法模式
    • 3.1. 有了简单工厂模式为什么还需要有工厂方法模式?
    • 3.2. 定义
    • 3.3. 代码实现
    • 3.4. 主要优点
    • 3.5. 主要缺点
    • 3.6. 适用场景
  • 4. 抽象工厂模式
    • 4.1. 产品等级结构与产品族
    • 4.2. 为什么需要抽象工厂模式?
    • 4.3. 定义
    • 4.4. 代码实现
    • 4.5. 主要优点
    • 4.6. 主要缺点
    • 4.7. 使用场景
  • 5. 总结

1. 为什么需要工厂模式?

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的方式,将对象的实例化过程与客户端代码解耦(即创建与使用解耦)。工厂模式的主要目的是提供一种灵活的对象创建机制,以便根据需求创建不同类型的对象。

以下是一些需要使用工厂模式的情况:

  1. 封装对象的创建逻辑:当对象的创建过程比较复杂,涉及到多个步骤或依赖关系时,可以使用工厂模式将对象的创建逻辑封装到工厂类中。这样客户端代码只需要与工厂类进行交互,而无需了解具体的创建细节。

  2. 实现对象的解耦:工厂模式可以将对象的实例化过程与客户端代码解耦,使得客户端代码不需要直接依赖具体的类。客户端只需要通过工厂类来获取所需的对象,使得代码更加灵活和可维护。

  3. 统一管理对象的创建:通过工厂模式,可以将对象的创建集中在工厂类中进行管理,避免了代码中多处重复的对象创建代码。这样可以更好地控制对象的创建逻辑,提高代码的复用性和可维护性。

  4. 实现产品族的创建:工厂模式可以用于创建产品族,即一组相关或相互依赖的产品对象。通过定义不同的工厂类来创建不同的产品族,可以使得创建过程更加灵活,同时也符合开闭原则,方便扩展新的产品族。

2. 简单工厂模式

2.1. 定义

简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。

2.2. 代码实现

#include <iostream>
#include <string>

// 抽象产品类
class Product {
public:
    virtual void Use() = 0;
};

// 具体产品类 A
class ConcreteProductA : public Product {
public:
    void Use() override {
        std::cout << "Using ConcreteProductA" << std::endl;
    }
};

// 具体产品类 B
class ConcreteProductB : public Product {
public:
    void Use() override {
        std::cout << "Using ConcreteProductB" << std::endl;
    }
};

// 简单工厂类
class SimpleFactory {
public:
    // 根据传入的参数创建不同的产品对象
    static Product* CreateProduct(const std::string& productType) {
        if (productType == "A") {
            return new ConcreteProductA();
        } else if (productType == "B") {
            return new ConcreteProductB();
        }
        return nullptr;
    }
};

int main() {
    // 使用简单工厂创建产品对象
    Product* productA = SimpleFactory::CreateProduct("A");
    if (productA) {
        productA->Use();
        delete productA;
    }

    Product* productB = SimpleFactory::CreateProduct("B");
    if (productB) {
        productB->Use();
        delete productB;
    }

    return 0;
}

2.3. 优点

  1. 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例。客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品。简单工厂模式实现了对象创建和使用的分离。
  2. 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。
  3. 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

2.4. 缺点

  1. 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
  2. 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
  3. 系统扩展困难。一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  4. 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

2.5. 适用场景

  1. 工厂类负责创建的对象比较少。由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  2. 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。

3. 工厂方法模式

3.1. 有了简单工厂模式为什么还需要有工厂方法模式?

在简单工厂模式中只提供一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它需要知道每个产品对象的创建细节,并决定何时实例化哪一个产品类。简单工厂模式最大的缺点是当有新产品要加入系统中时,必须修改工厂类,需要在其中加入必要的业务逻辑,这违背了开闭原则。此外,在简单工厂模式中,所有的产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。在工厂方法模式中,不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构。工厂方法模式定义如下:

3.2. 定义

工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。

3.3. 代码实现

#include <iostream>
#include <string>

// 抽象产品类
class Product {
public:
    virtual void Use() = 0;
};

// 具体产品类 A
class ConcreteProductA : public Product {
public:
    void Use() override {
        std::cout << "Using ConcreteProductA" << std::endl;
    }
};

// 具体产品类 B
class ConcreteProductB : public Product {
public:
    void Use() override {
        std::cout << "Using ConcreteProductB" << std::endl;
    }
};

// 抽象工厂类
class Factory {
public:
    virtual Product* CreateProduct() = 0;
};

// 具体工厂类 A
class ConcreteFactoryA : public Factory {
public:
    Product* CreateProduct() override {
        return new ConcreteProductA();
    }
};

// 具体工厂类 B
class ConcreteFactoryB : public Factory {
public:
    Product* CreateProduct() override {
        return new ConcreteProductB();
    }
};

int main() {
    // 使用工厂方法创建产品对象
    Factory* factoryA = new ConcreteFactoryA();
    Product* productA = factoryA->CreateProduct();
    if (productA) {
        productA->Use();
        delete productA;
    }
    delete factoryA;

    Factory* factoryB = new ConcreteFactoryB();
    Product* productB = factoryB->CreateProduct();
    if (productB) {
        productB->Use();
        delete productB;
    }
    delete factoryB;

    return 0;
}

工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足。工厂方法模式是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。

3.4. 主要优点

(1)在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节。用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
(2)基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类。
(3)使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合开闭原则。

3.5. 主要缺点

(1)在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
(2)由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到反射等技术,增加了系统的实现难度

3.6. 适用场景

(1)客户端不知道其所需要的对象的类。在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。
(2)抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。

4. 抽象工厂模式

工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题。但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产。

4.1. 产品等级结构与产品族

在工厂方法模式中,具体工厂负责生产具体的产品,每个具体工厂对应一种具体产品,工厂方法具有唯一性。一般情况下,一个具体工厂中只有一个或者一组重载的工厂方法。但是,有时希望一个工厂可以提供多个产品对象,而不是单一的产品对象。例如一个电器工厂,它可以生产电视机、电冰箱、空调等多种电器,而不是只生产某一种电器。为了更好地理解抽象工厂模式,这里先引入如下两个概念:(1)产品等级结构。产品等级结构即产品的继承结构,例如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。(2)产品族。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。例如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
在这里插入图片描述

只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一确定这个产品。

4.2. 为什么需要抽象工厂模式?

当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时,就可以使用抽象工厂模式。抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。
在这里插入图片描述
在上图中,每一个具体工厂可以生产属于一个产品族的所有产品,例如海尔工厂生产海尔电视机、海尔冰箱和海尔空调,所生产的产品又位于不同的产品等级结构中。如果使用工厂方法模式,实现上图所示结构需要提供9个具体工厂,而使用抽象工厂模式只需要提供3个具体工厂,极大地减少了系统中类的个数。

4.3. 定义

抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

4.4. 代码实现

#include <iostream>
#include <string>

// 抽象产品类 A
class AbstractProductA {
public:
    virtual void Use() = 0;
    virtual ~AbstractProductA() {}
};

// 具体产品类 A1
class ConcreteProductA1 : public AbstractProductA {
public:
    void Use() override {
        std::cout << "Using ConcreteProductA1" << std::endl;
    }
};

// 具体产品类 A2
class ConcreteProductA2 : public AbstractProductA {
public:
    void Use() override {
        std::cout << "Using ConcreteProductA2" << std::endl;
    }
};

// 抽象产品类 B
class AbstractProductB {
public:
    virtual void Use() = 0;
    virtual ~AbstractProductB() {}
};

// 具体产品类 B1
class ConcreteProductB1 : public AbstractProductB {
public:
    void Use() override {
        std::cout << "Using ConcreteProductB1" << std::endl;
    }
};

// 具体产品类 B2
class ConcreteProductB2 : public AbstractProductB {
public:
    void Use() override {
        std::cout << "Using ConcreteProductB2" << std::endl;
    }
};

// 抽象工厂类
class AbstractFactory {
public:
    virtual AbstractProductA* CreateProductA() = 0;
    virtual AbstractProductB* CreateProductB() = 0;
    virtual ~AbstractFactory() {}
};

// 具体工厂类 A
class ConcreteFactoryA : public AbstractFactory {
public:
    AbstractProductA* CreateProductA() override {
        return new ConcreteProductA1();
    }

    AbstractProductB* CreateProductB() override {
        return new ConcreteProductB1();
    }
};

// 具体工厂类 B
class ConcreteFactoryB : public AbstractFactory {
public:
    AbstractProductA* CreateProductA() override {
        return new ConcreteProductA2();
    }

    AbstractProductB* CreateProductB() override {
        return new ConcreteProductB2();
    }
};

int main() {
    // 使用抽象工厂创建产品对象
    AbstractFactory* factoryA = new ConcreteFactoryA();
    AbstractProductA* productA = factoryA->CreateProductA();
    AbstractProductB* productB = factoryA->CreateProductB();
    if (productA) {
        productA->Use();
        delete productA;
    }
    if (productB) {
        productB->Use();
        delete productB;
    }
    delete factoryA;

    AbstractFactory* factoryB = new ConcreteFactoryB();
    AbstractProductA* productA2 = factoryB->CreateProductA();
    AbstractProductB* productB2 = factoryB->CreateProductB();
    if (productA2) {
        productA2->Use();
        delete productA2;
    }
    if (productB2) {
        productB2->Use();
        delete productB2;
    }
    delete factoryB;

    return 0;
}

抽象工厂模式是工厂方法模式的进一步延伸,由于它提供了功能更为强大的工厂类并且具备较好的可扩展性,在软件开发中得以广泛应用,尤其是在一些框架和API类库的设计中。

4.5. 主要优点

(1)抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了在抽象工厂中声明的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
(2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
(3)增加新的产品族很方便,无须修改已有系统,符合开闭原则。

4.6. 主要缺点

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则。

4.7. 使用场景

(1)一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
(2)系统中有多于一个的产品族,而每次只使用其中某一个产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
(3)属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束。例如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,此时具有一个共同的约束条件:操作系统的类型。
(4)产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。

5. 总结

简单工厂模式适用于创建对象较少且变化不频繁的情况,工厂方法模式适用于创建对象较多且需要灵活扩展的情况,而抽象工厂模式适用于创建一组相关对象的情况。

所有的工厂模式都强调一点:两个类A和B之间的关系应该仅仅是A创建B或是A使用B,而不能两种关系都有。将对象的创建和使用分离,也使得系统更加符合单一职责原则,有利于对功能的复用和系统的维护。此外,将对象的创建和使用分离还有一个好处:防止用来实例化一个类的数据和代码在多个类中到处都是,可以将有关创建的知识搬移到一个工厂类中。因为有时候创建一个对象不只是简单调用其构造函数,还需要设置一些参数,可能还需要配置环境。如果将这些代码散落在每一个创建对象的客户类中,势必会出现代码重复、创建蔓延的问题,而这些客户类其实无须承担对象的创建工作,只需使用已创建好的对象就可以了。此时,可以引入工厂类来封装对象的创建逻辑和客户代码的实例化/配置选项。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python怎么修改进程名称

目录 一、进程名称的概念 二、Python修改进程名称的方法 三、代码示例与使用说明 四、注意事项 五、适用场景 六、总结 Python是一种强大的编程语言&#xff0c;广泛应用于各种应用程序的开发。在Python中&#xff0c;修改进程名称可以通过多种方式实现。下面我们将深入探…

红队打靶练习:SAR: 1

目录 信息收集 1、arp 2、netdiscover 3、nmap 4、nikto 5、whatweb 小结 目录探测 1、gobuster 2、dirsearch WEB CMS 1、cms漏洞探索 2、RCE漏洞利用 提权 get user.txt 本地提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface:…

【Linux C | 文件操作】获取文件元数据的几个函数 | stat、fstat、lstat

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

吸烟者问题-第三十一天

目录 问题描述 解决问题 是否需要设置一个专门的互斥信号量&#xff1f; 结论 问题描述 该题属于”生产者-消费者”问题&#xff0c;更详细的说应该是“可生产多种产品的单生产者-多消费者” 解决问题 1、 关系分析&#xff1a;找出题目中描述的各个进程&#xff0c;分析…

(一)输出输入

文章目录 输出printf输出格式控制常见的几种格式输出小数输出很奇特指定位数对齐方式 代码现象 输入scanf输入格式控制输入坑代码现象 %c 格式控制的坑混合类型输入问题 输出printf 输出格式控制 如&#xff1a;%(占位符/格式字符) printf(“a%d”,a); 常见的几种格式输出 …

海外网红营销:母婴品牌提升影响力和市场份额的绝佳途径

随着全球化的加速和社交媒体的普及&#xff0c;越来越多的母婴品牌开始寻求海外市场拓展。在这个过程中&#xff0c;海外网红营销成为了品牌方们青睐的策略之一。本文Nox聚星将和大家探讨母婴品牌如何利用海外网红营销来提升品牌影响力并拓展市场份额。 母婴品牌的核心消费者是…

BIOS:计算机中的特洛伊木马

内容概述&#xff1a; 由于主板制造商在计算机启动时用来显示品牌徽标的图像分析组件相关的问题&#xff0c;多个安全漏洞&#xff08;统称为 LogoFAIL&#xff09;允许攻击者干扰计算机设备的启动过程并安装 bootkit。x86 和 ARM 设备都面临风险。主板固件供应链安全公司 Bin…

02--数据定义语言DDL

1、数据定义语言DDL 1.1 操作数据库-DDL 创建数据库 create database 数据库名称; 创建数据库&#xff0c;并指定字符集 create database 数据库名称 character set 字符集名; 查询所有数据库的名称 show databases; 查询某个数据库的字符集:查询某个数据库的创建语句及字…

【Matlab】ELM极限学习机时序预测算法(附代码)

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88681649 一&#xff0c;概述 ELM&#xff08;Extreme Learning Machine&#xff09;是一种单层前馈神经网络结构&#xff0c;与传统神经网络不同的是&#xff0c;ELM的隐层神经元权重以及偏置都是随机产生的…

tecplot360 提取某一点随时加变化的参数

tecplot360 提取某一点随时加变化的参数 效果过程录制宏打开所有数据&#xff08;都进来所有的data数据&#xff09; 效果 如下&#xff0c;红点处随时间变化的温度曲线 过程 简单理解就是将所有计算的data帧中固定点的参数取出来 所以先录制宏&#xff0c;然后应用宏自动取…

大模型时代下AIGC新浪潮

大模型时代下AIGC新浪潮 文章目录 大模型时代下AIGC新浪潮1. **相关概念**2. **迎接大模型时代**3. **ChatGPT引爆AIGC产业**4. **从产业链宏观看AIGC**1. **上游&#xff1a;基础层**2. **中游&#xff1a;技术层/模型层**1. **模型层介绍**2. **预训练大模型分类与介绍** 3. …

品优购实战案例

1. 开发工具 VScode 、Photoshop&#xff08;fw&#xff09;、主流浏览器&#xff08;以Chrome浏览器为主&#xff09; 2. 技术栈  利用 HTML5 CSS3 手动布局&#xff0c;可以大量使用 H5 新增标签和样式  采取结构与样式相分离&#xff0c;模块化开发  良好的代码规范有…

js常用事件演示

目录 JS事件的具体方法 窗口事件 表单事件 键盘事件 鼠标事件 知识小拓展 JS事件的具体方法 我们用到JavaScript的时候js的事件就显得特别重要了 事件名说明onsubmit当表单提交时触发该事件onclick鼠标单击事件ondblclick鼠标双击事件onblur元素失去焦点onfocus元素获得…

Eureka服务注册与发现中心

简介 Spring Cloud封装了Netflix 公司开发的Eureka模块来实现服务治理 在传统的RPC远程调用框架中&#xff0c;管理每个服务与服务之间依赖关系比较复杂&#xff0c;管理比较复杂&#xff0c;所以需要使用服务治理&#xff0c;管理服务于服务之间依赖关系&#xff0c;可以实现…

打印菱形和金字塔类型(总结)

首先&#xff0c;在之前的学习中&#xff0c;我们了解了菱形的打印&#xff0c;今天我们来对金字塔和菱形这类打印图形的问题&#xff0c;我们来做一个总结。 这个总结的来源是这今天做了一道题 这道题的答案如下 这个题做起来并不难&#xff0c;拓展到这类问题中&#xff0c;…

【驱动序列】简单聊聊开发驱动程序的缘由和驱动程序基本信息

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》&#xff0c;这是《驱动程序》专栏序列文章。 这是2024年第4篇文章&#xff0c;此篇文章是结合了C#知识点实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xf…

面向对象(类和对象,对象内存图,成员变量和局部变量,封装,构造方法)

1. 类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 &#xff0c;所以我们也常常说万物皆对象。 类 类的理解 类是对现实生活中一类具有共同属性和行为的事物的抽象类是对象的数据类型&#xff0c;类是具有相同属性和行为的一组对象的集合简单理解&#xff1a;类就是对…

cJSON代码解读

1、背景 cJSON用了很久&#xff0c;但是对它一直不太了解。这次向添加对long long类型的支持&#xff0c;一直出问题。因为有以前添加两位小数float的经历&#xff0c;我觉得会很轻松&#xff0c;没想到翻车了。于是有了这边文档&#xff0c;阅读了部分博主对cJSON的解析&…

第二十七章 正则表达式

第二十七章 正则表达式 1.正则快速入门2.正则需求问题3.正则底层实现14.正则底层实现25.正则底层实现36.正则转义符7.正则字符匹配8.字符匹配案例19.字符匹配案例211.选择匹配符&#xff08;|&#xff09;12.正则限定符{n}{n,m}&#xff08;1个或者多个&#xff09;*(0个或者多…

OpenGL FXAA抗锯齿算法(Qt,Consloe版本)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 之前已经提供了使用VCG读取Mesh的方式,接下来就需要针对读取的网格数据进行一些渲染操作了。在绘制Mesh数据时总会遇到图形的抗锯齿问题,OpenGL本身已经为我们提供了一种MSAA技术,但该技术对于一些实时渲染性能有…