登錄 |創建賬號 |找回密碼
查看: 89|回復: 2

c++14通过字符串动态实例化

[複製鏈接]

23

主題

6

回帖

130

積分

管理員

Rank: 9Rank: 9Rank: 9

積分
130
發表於 2024-3-26 14:30:17 | 顯示全部樓層 |閱讀模式

文件架构:


animal.h
  1. #ifndef ANIMAL_H
  2. #define ANIMAL_H

  3. #include <iostream>

  4. class Animal {
  5. public:
  6.     virtual void speak() = 0;
  7.     virtual ~Animal() {}
  8. };

  9. #endif // ANIMAL_H
複製代碼
animal_factory.h
  1. #ifndef ANIMAL_FACTORY_H
  2. #define ANIMAL_FACTORY_H

  3. #include "animal.h"
  4. #include <memory>
  5. #include <string>
  6. #include <unordered_map>
  7. #include <functional>

  8. class AnimalFactory {
  9. public:
  10.     using CreateFunc = std::function<std::unique_ptr<Animal>()>;

  11.     static void registerAnimal(const std::string& name, CreateFunc func);
  12.     static std::unique_ptr<Animal> createAnimal(const std::string& name);

  13. private:
  14.     // 将getRegistry声明为一个私有的静态成员函数
  15.     static std::unordered_map<std::string, CreateFunc>& getRegistry();
  16. };

  17. template<typename T>
  18. struct Registrator {
  19.     Registrator(const std::string& name) {
  20.         AnimalFactory::registerAnimal(name, &T::create);
  21.     }
  22. };

  23. #endif // ANIMAL_FACTORY_H
複製代碼
animal_factory.cpp
  1. #include "animal_factory.h"
  2. #include "cat.h"
  3. #include "dog.h"

  4. void AnimalFactory::registerAnimal(const std::string& name, CreateFunc func) {
  5.     getRegistry()[name] = func;
  6. }

  7. std::unique_ptr<Animal> AnimalFactory::createAnimal(const std::string& name) {
  8.     const auto& reg = getRegistry();
  9.     auto it = reg.find(name);
  10.     if (it != reg.end()) {
  11.         return it->second();
  12.     }
  13.     return nullptr;
  14. }

  15. // 定义getRegistry,以满足之前的声明
  16. std::unordered_map<std::string, AnimalFactory::CreateFunc>& AnimalFactory::getRegistry() {
  17.     static std::unordered_map<std::string, CreateFunc> instance;
  18.     return instance;
  19. }
複製代碼
cat.h
  1. #ifndef CAT_H
  2. #define CAT_H

  3. #include "animal.h"
  4. #include <memory>

  5. class Cat : public Animal {
  6. public:
  7.     void speak() override;
  8.     static std::unique_ptr<Animal> create();
  9. };

  10. #endif // CAT_H
複製代碼
cat.cpp
  1. #include "animal_factory.h"
  2. #include "cat.h"

  3. void Cat::speak() {
  4.     std::cout << "Meow" << std::endl;
  5. }

  6. std::unique_ptr<Animal> Cat::create() {
  7.     return std::make_unique<Cat>();
  8. }

  9. static Registrator<Cat> reg_cat("cat");
複製代碼
dog.h
  1. #ifndef DOG_H
  2. #define DOG_H

  3. #include "animal.h"
  4. #include <memory>

  5. class Dog : public Animal {
  6. public:
  7.     void speak() override;
  8.     static std::unique_ptr<Animal> create();
  9. };

  10. #endif // DOG_H
複製代碼
dog.cpp
  1. #include "animal_factory.h"
  2. #include "dog.h"

  3. void Dog::speak() {
  4.     std::cout << "Woof" << std::endl;
  5. }

  6. std::unique_ptr<Animal> Dog::create() {
  7.     return std::make_unique<Dog>();
  8. }

  9. static Registrator<Dog> reg_dog("dog");
複製代碼
main.cpp
  1. #include "animal_factory.h"
  2. #include <iostream>

  3. int main() {
  4.     auto cat = AnimalFactory::createAnimal("cat");
  5.     if (cat) cat->speak();

  6.     auto dog = AnimalFactory::createAnimal("dog");
  7.     if (dog) dog->speak();

  8.     return 0;
  9. }
複製代碼


本帖子中包含更多資源

您需要 登錄 才可以下載或查看,沒有賬號?創建賬號

x
回復

使用道具 舉報

23

主題

6

回帖

130

積分

管理員

Rank: 9Rank: 9Rank: 9

積分
130
 樓主| 發表於 2024-3-26 14:31:29 | 顯示全部樓層
编译命令:
  1. g++ -std=c++14 -o animal_app animal_factory.cpp cat.cpp dog.cpp main.cpp
複製代碼

效果:
  1. root@iZ8vb21cs5hzwls5h5s2hbZ:/cpp/240326# g++ -std=c++14 -o animal_app animal_factory.cpp cat.cpp dog.cpp main.cpp
  2. root@iZ8vb21cs5hzwls5h5s2hbZ:/cpp/240326# ./animal_app
  3. Meow
  4. Woof
  5. root@iZ8vb21cs5hzwls5h5s2hbZ:/cpp/240326#
複製代碼
回復

使用道具 舉報

23

主題

6

回帖

130

積分

管理員

Rank: 9Rank: 9Rank: 9

積分
130
 樓主| 發表於 2024-3-26 14:35:53 | 顯示全部樓層
Makefile:
  1. CXX = g++
  2. CXXFLAGS = -std=c++14 -Wall
  3. LDFLAGS =
  4. OBJFILES = animal_factory.o cat.o dog.o main.o
  5. TARGET = animal_app

  6. all: $(TARGET)

  7. $(TARGET): $(OBJFILES)
  8.         $(CXX) $(LDFLAGS) -o $(TARGET) $(OBJFILES)

  9. %.o: %.cpp
  10.         $(CXX) $(CXXFLAGS) -c $<

  11. clean:
  12.         rm -f $(OBJFILES) $(TARGET)
複製代碼
回復

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 創建賬號

本版積分規則

Archiver|手機版|小黑屋|九派社區 ( 苏ICP备07501547号-12 )

GMT+8, 2024-5-21 07:10 , Processed in 0.048076 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回復 返回頂部 返回列表