c++模拟反射实现简单工厂
if else写多了挺麻烦,借鉴网上的例子,重新手撸一边。
ibank.h
#pragma once
class IBank {
public:
virtual ~IBank() {}
virtual void GetMsg() = 0;
virtual void SetMsg() = 0;
virtual void ParseMsg() = 0;
};
banks.h
#pragma once
#include <iostream>
#include "ibank.h"
#define FUNCTION_NAME std::cout << __FUNCTION__ << '\n';
#define CLASS_MEMBER(name) \
virtual void name() override { FUNCTION_NAME }
class BOCBank : public IBank {
public:
CLASS_MEMBER(GetMsg)
CLASS_MEMBER(SetMsg)
CLASS_MEMBER(ParseMsg)
};
class BCSBank : public IBank {
public:
CLASS_MEMBER(GetMsg)
CLASS_MEMBER(SetMsg)
CLASS_MEMBER(ParseMsg)
};
利用编译器实现全局静态注册方法 GlobalRegister.h
#pragma once
#include <string>
#include <functional>
#include <map>
typedef std::function<void*()> bank_generator_t;
class BankRegister {
public:
static void* NewBank(const std::string& class_name) {
std::map<std::string, bank_generator_t>::iterator it =
bank_store.find(class_name);
if (it != bank_store.end()) {
return it->second();
} else {
return nullptr;
}
}
static void Register(const std::string& class_name,
bank_generator_t bank_generator) {
std::map<std::string, bank_generator_t>::iterator it =
bank_store.find(class_name);
if (it == bank_store.end()) {
bank_store.emplace(class_name, bank_generator);
}
}
private:
static std::map<std::string, bank_generator_t> bank_store;
};
std::map<std::string, bank_generator_t> BankRegister::bank_store;
class ImplRegister {
public:
ImplRegister(const std::string& class_name, bank_generator_t bank_generator) {
BankRegister::Register(class_name, bank_generator);
}
};
#define REGISTER_CLASS(class_name) \
class BankRegister##class_name { \
public: \
static void* BankGenerator() { return new class_name; } \
\
private: \
static const ImplRegister implRegister_; \
}; \
const ImplRegister BankRegister##class_name::implRegister_( \
#class_name, &BankRegister##class_name::BankGenerator);
简单工厂 SimpleFactory.h
#pragma once
#include <memory>
#include <string>
class IBank;
class SimpleFactory {
public:
static std::shared_ptr<IBank> CreateBank(const std::string& class_name);
};
SimpleFactory.cpp
#include "SimpleFactory.h"
#include "GlobalRegister.h"
#include "banks.h"
REGISTER_CLASS(BCSBank)
REGISTER_CLASS(BOCBank)
std::shared_ptr<IBank> SimpleFactory::CreateBank(
const std::string& class_name) {
return std::shared_ptr<IBank>(
static_cast<IBank*>(BankRegister::NewBank(class_name)));
}
测试代码
#include <iostream>
#include "SimpleFactory.h"
#include "ibank.h"
int main(int argc, char* argv[]) {
const char* names[] = {"BCSBank", "BOCBank"};
for (auto name : names) {
std::shared_ptr<IBank> bank = SimpleFactory::CreateBank(name);
if (bank) {
bank->SetMsg();
bank->GetMsg();
bank->ParseMsg();
std::cout << '\n';
}
}
return EXIT_SUCCESS;
}
运行结果:
|