C++工厂类模板 code 和使用

REGISTER_FACTORY 宏定义 creators

#include <iostream>
#include <map>
#include <string>
#include <memory>
#include <functional>

using namespace std;

// Base class
class Animal {
public:
    virtual void makeSound() = 0;
    virtual unique_ptr<Animal> clone() = 0;
};

// Derived classes
class Dog : public Animal {
public:
    void makeSound() {
        cout << "Woof!" << endl;
    }

    unique_ptr<Animal> clone() {
        return make_unique<Dog>(*this);
    }
};

class Cat : public Animal {
public:
    void makeSound() {
        cout << "Meow!" << endl;
    }

    unique_ptr<Animal> clone() {
        return make_unique<Cat>(*this);
    }
};

// Factory class
class AnimalFactory {
public:
    static AnimalFactory* getInstance() {
        static AnimalFactory factory;
        return &factory;
    }

    void registerType(string type, function<unique_ptr<Animal>()> creator) {
        creators[type] = creator;
    }

    unique_ptr<Animal> createType(string type) {
        if (creators.find(type) != creators.end()) {
            return creators[type]();
        }
        return nullptr;
    }

private:
    AnimalFactory() = default;
    AnimalFactory(const AnimalFactory&) = delete;
    AnimalFactory& operator=(const AnimalFactory&) = delete;

    map<string, function<unique_ptr<Animal>()>> creators;
};

// Macro definition for registering objects with the factory
#define REGISTER_FACTORY(type) \
    static unique_ptr<Animal> create_##type() { \
            return make_unique<type>(); \
                } \
                    struct type##FactoryRegister { \
                            type##FactoryRegister() { \
                                        AnimalFactory::getInstance()->registerType(#type, create_##type); \
                                                } \
                                                    }; \
                                                        static type##FactoryRegister type##_register;

// Register objects with the factory using the macro definition
REGISTER_FACTORY(Dog);
REGISTER_FACTORY(Cat);

// Main function
int main() {
    // Create objects using the factory
    unique_ptr<Animal> obj1 = AnimalFactory::getInstance()->createType("Dog");
    unique_ptr<Animal> obj2 = AnimalFactory::getInstance()->createType("Cat");

    // Call the makeSound() function for each object
    obj1->makeSound();
    obj2->makeSound();

    return 0;
}

在这个例子中,我们定义了一个Animal基类及其两个派生类Dog和Cat。我们还定义了一个AnimalFactory类,该类负责创建对象并将其添加到对象映射中。我们使用REGISTER_FACTORY宏定义来实现对象的注册,同时宏定义还定义了一个静态函数create_##type,用于创建对象并将其添加到工厂中。

在main函数中,我们使用AnimalFactory::getInstance()来获取AnimalFactory的实例,并通过createType()函数创建对象。最后,我们再通过unique_ptr进行智能指针管理以避免内存泄漏。

这是一个使用REGISTER_FACTORY宏定义和creators的完整C++代码示例。

工厂类模板

#include <iostream>
using namespace std;

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

class Shape {
public:
    virtual void draw() = 0;
};

class Rectangle : public Shape {
public:
    void draw() {
        cout << "Drawing a rectangle" << endl;
    }
};

class Circle : public Shape {
public:
    void draw() {
        cout << "Drawing a circle" << endl;
    }
};

int main() {
    Shape* rect = Factory<Rectangle>::create();
    rect->draw();
    Shape* circle = Factory<Circle>::create();
    circle->draw();
    return 0;
}

在这个代码中,有一个工厂类模板Factory,它的类型参数为T。工厂类有一个静态函数create(),该函数返回一个指向类型为T的对象的指针。

我们还有一个抽象类Shape,其中有一个纯虚函数draw()。我们还有两个具体的类Rectangle和Circle,它们都继承自Shape,并实现了draw()函数。

在main()函数中,我们使用Factory类模板实例化Rectangle和Circle类型的工厂,使用这些工厂创建Rectangle和Circle类的对象,并调用它们的draw()函数以打印出适当的消息。

工厂数据类型类模板

#include <iostream>
#include <typeinfo>
using namespace std;

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

template <typename T>
class DataType {
public:
    void printType() {
        cout << typeid(T).name() << endl;
    }
};

int main() {
    DataType<int> intData;
    intData.printType();
    DataType<float> floatData;
    floatData.printType();
    Factory<DataType<int>> dataTypeFactory;
    DataType<int> newIntData = dataTypeFactory.create();
    newIntData.printType();
    return 0;
}

在这个代码中,我们有一个工厂类Factory和一个数据类型类模板DataType。工厂类模板中的类型参数为T,并有一个静态函数create(),该函数返回一个类型为T的对象。

DataType类模板中的类型参数为T,并有一个printType()函数,该函数使用C++的typeid运算符打印出模板参数的类型。

在main()函数中,我们首先使用DataType类模板创建intData和floatData对象,并使用它们的printType()函数打印出类型。然后,我们使用Factory类模板创建DataType<int>类型的工厂,并使用该工厂创建一个新的intData对象。最后,我们再次调用newIntData对象的printType()函数来打印其类型。

这个示例展示了如何使用C++的类模板和工厂模式来创建并操作不同数据类型的对象

类型擦除和可调用对象概念来注册子类数据模板

是一个使用类型擦除和可调用对象概念来注册和创建子类数据模板的动物工厂类。具体实现中,我们使用模板元编程技术来遍历模板参数包中的每个类型,并为每个类型注册一个创建器。然后,使用可调用对象的概念来创建不同类型的子类数据模板对象,并将其存储为智能指针类型。

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

// 基类
class Animal {
public:
    virtual void speak() = 0;
};

// 子类
class Dog : public Animal {
public:
    void speak() {
        std::cout << "汪汪!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void speak() {
        std::cout << "喵喵!" << std::endl;
    }
};

class Elephant : public Animal {
public:
    void speak() {
        std::cout << "大象!" << std::endl;
    }
};

class Bear : public Animal {
public:
    void speak() {
        std::cout << "蜜蜂!" << std::endl;
    }
};

// 工厂类
class AnimalFactory {
public:
    // 注册子类数据模板
    template <typename T>
    static void registerAnimal(const std::string& type) {
        creators[type] = []() -> std::unique_ptr<Animal> {
            return std::make_unique<T>();
        };
    }

    // 创建动物对象
    static std::unique_ptr<Animal> createAnimal(const std::string& type) {
        auto it = creators.find(type);
        if (it != creators.end()) {
            return it->second();
        } else {
            return nullptr;
        }
    }

private:
    // 类型擦除和可调用对象概念
    static std::unordered_map<std::string, std::function<std::unique_ptr<Animal>()>> creators;
};

std::unordered_map<std::string, std::function<std::unique_ptr<Animal>()>> AnimalFactory::creators;

int main() {
    // 注册子类数据模板
    AnimalFactory::registerAnimal<Dog>("dog");
    AnimalFactory::registerAnimal<Elephant>("elephant");
    AnimalFactory::registerAnimal<Bear>("bear");
    

    // 创建动物对象
    std::string type;
    std::cout << "请输入要创建的动物类型:";
    std::cin >> type;

    auto animal = AnimalFactory::createAnimal(type);
    if (animal) {
        animal->speak();
    } else {
        std::cout << "不支持该类型的动物!" << std::endl;
    }

    return 0;
}

在上面的代码中,我们定义了两个子类数据模板Cat和Dog,它们继承自Animal类,并各自实现了speak()函数。我们创建了一个名为AnimalFactory的类,它使用类型擦除和可调用对象的概念来注册和创建不同类型的动物对象。在registerAnimal()函数中,我们使用模板元编程技术来为每个类型注册一个创建器,并将其存储为泛型可调用对象。在createAnimal()函数中,我们使用已注册的创建器来创建指定类型的动物对象,并将其存储为智能指针类型。

在main函数中,我们使用AnimalFactory类来注册和创建不同类型的动物对象,并使用智能指针类型推导来创建具体的动物对象,并调用它们的speak()函数来输出它们的声音。

总之,使用类型擦除和可调用对象的概念可以让我们注册和创建不同类型的子类数据模板,并使其类型安全和可维护。

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏马潜行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值