工厂模式是一种常用的设计模式,用于创建对象,而不需要指定将要创建的对象的具体类。C++模板可以用来实现一个通用的工厂模式,使得工厂能够创建任何类型的对象,只要这些对象遵循了一定的创建接口。以下是使用C++模板实现工厂模式的一个基本示例:

步骤 1:定义产品接口

class Product {
public:
    virtual ~Product() = default;
    virtual void Operation() const = 0;
};

步骤 2:实现具体产品

class ProductA : public Product {
public:
    void Operation() const override {
        std::cout << "Operation of ProductA" << std::endl;
    }
};

class ProductB : public Product {
public:
    void Operation() const override {
        std::cout << "Operation of ProductB" << std::endl;
    }
};

步骤 3:实现模板工厂类

接下来,实现一个模板工厂类,它可以创建任何遵循Product接口的类的实例。

template <typename T>
class Factory {
public:
    static T* Create() {
        return new T();
    }
};

步骤 4:使用工厂创建对象

最后,使用工厂类创建具体产品对象的实例。

int main() {
    // 使用工厂创建ProductA的实例
    Product* productA = Factory<ProductA>::Create();
    productA->Operation();
    delete productA;

    // 使用工厂创建ProductB的实例
    Product* productB = Factory<ProductB>::Create();
    productB->Operation();
    delete productB;

    return 0;
}

在这个简单的例子中,Factory类是一个模板类,它有一个静态方法Create,这个方法可以创建任何类型的对象,只要这个类型遵循了Product接口。这种方法的好处是它非常灵活,可以很容易地添加新的产品类型,而不需要修改工厂类。此外,由于使用了模板,这种方法在编译时就确定了对象的类型,避免了运行时类型识别(RTTI)的开销,提高了效率。

根据不同的字符串输入创建不同的类实例(实际开发中更常用)

要根据不同的字符串输入创建不同的类实例,我们需要将字符串映射到特定的类构造函数上。这通常涉及到使用一个注册机制,其中每个类的构造函数都与一个特定的字符串关联。这种方法不能直接通过模板实现,因为模板需要在编译时解析其参数,而字符串的具体值通常是在运行时才确定的。
下面是一个简化的示例,演示如何实现这样的工厂模式:

定义工厂类

这里我们使用一个函数指针映射(也可以使用std::function)来注册和创建对象。

#include <iostream>
#include <unordered_map>
#include <functional>
#include <memory>

// 工厂类,不再是模板类
class Factory {
private:
    std::unordered_map<std::string, std::function<Product*()>> registry;

public:
    void Register(const std::string& name, std::function<Product*()> constructor) {
        registry[name] = constructor;
    }

    Product* Create(const std::string& name) const {
        auto it = registry.find(name);
        if (it != registry.end()) {
            return it->second();
        }
        std::cout << "Class name " << name << " not registered." << std::endl;
        return nullptr;
    }
};

注册类并使用工厂创建对象

int main() {
    Factory factory;

    // 注册类
    factory.Register("ProductA", []() -> Product* { return new ProductA(); });
    factory.Register("ProductB", []() -> Product* { return new ProductB(); });

    // 根据字符串创建对象
    std::unique_ptr<Product> productA(factory.Create("ProductA"));
    if (productA) {
        productA->Operation();
    }

    std::unique_ptr<Product> productB(factory.Create("ProductB"));
    if (productB) {
        productB->Operation();
    }

    // 尝试创建一个未注册的类
    std::unique_ptr<Product> productC(factory.Create("UnregisteredProduct"));
    if (productC) {
        productC->Operation();
    }

    return 0;
}

在这个例子中,Factory类有一个注册方法Register,它将类的名称映射到一个lambda表达式,该表达式返回该类的新实例。通过这个注册机制,工厂可以在运行时根据字符串名称创建相应的类实例。这种方法允许在不修改工厂代码的情况下添加新的产品类型,提高了代码的扩展性。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐