工厂类
factory.h
#pragma once
#include <functional>
#include <memory>
#include <unordered_map>
template <typename T, typename... Args>
class Factory {
public:
static Factory& Instance() {
if (!instance_) {
instance_ = new Factory<T, Args...>();
}
return *instance_;
}
void Register(const std::string& name,
std::function<std::shared_ptr<T>(Args...)> creator) {
creators_[name] = creator;
}
std::shared_ptr<T> Create(const std::string& name, Args... args) {
return creators_.find(name) == creators_.end() ? std::shared_ptr<T>()
: creators_[name](args...);
}
private:
Factory() {}
static Factory<T, Args...>* instance_;
std::unordered_map<std::string, std::function<std::shared_ptr<T>(Args...)>>
creators_;
};
template <typename T, typename... Args>
Factory<T, Args...>* Factory<T, Args...>::instance_ = nullptr;
注册类
register.h
#pragma once
#include "factory.h"
template <typename Base, typename Impl, typename... Args>
class Register {
public:
explicit Register(const std::string& name) {
Factory<Base, Args...>& factory = Factory<Base, Args...>::Instance();
factory.Register(name, [](Args... args) {
return std::shared_ptr<Base>(new Impl(args...));
});
}
};
基类
shoes.h
#pragma once
#include "factory.h"
class Shoes {
public:
explicit Shoes(const int& number) : number_(number) {};
virtual void Message() = 0;
virtual ~Shoes() = default;
protected:
const int number_;
};
typedef Factory<Shoes, int> ShoesFactory;
car.h
#pragma once
#include "factory.h"
class Car {
public:
explicit Car(const int& number, const std::string &size) : number_(number), size_(size) {};
virtual void Message() = 0;
virtual ~Car() = default;
protected:
const int number_;
const std::string size_;
};
typedef Factory<Car, int, std::string> CarFactory;
派生类
nike.cc
#include <iostream>
#include "register.h"
#include "shoes.h"
class Nike : public Shoes {
public:
explicit Nike(const int& number) : Shoes(number) {}
void Message() {
std::cout << number_ << " Nike shoes !" << std::endl;
}
};
namespace {
Register<Shoes, Nike, int> _("nike"); // 注册该类,namespace{}防止变量"_"重复定义,.cc文件才会自动执行该语句,.h文件不执行
}
anta.cc
#include <iostream>
#include "register.h"
#include "shoes.h"
class Anta : public Shoes {
public:
explicit Anta(const int& number) : Shoes(number) {}
void Message() {
std::cout << number_ << " Anta shoes !" << std::endl;
}
};
namespace {
Register<Shoes, Anta, int> _("anta");
}
benz.cc
#include <iostream>
#include "register.h"
#include "car.h"
class Benz : public Car {
public:
explicit Benz(const int& number, const std::string &size) : Car(number, size) {}
void Message() {
std::cout << number_ << " " << size_ << " Benz car !" << std::endl;
}
};
namespace {
Register<Car, Benz, int, std::string> _("benz");
}
audi.cc
#include <iostream>
#include "register.h"
#include "car.h"
class Audi : public Car {
public:
explicit Audi(const int& number, const std::string &size) : Car(number, size) {}
void Message() {
std::cout << number_ << " " << size_ << " Audi car !" << std::endl;
}
};
namespace {
Register<Car, Audi, int, std::string> _("audi");
}
主函数
main.cc
#include "factory.h"
#include "shoes.h"
#include "car.h"
int main(int argc, char** argv) {
auto nike_shoes = ShoesFactory::Instance().Create("nike", 1);
if (nike_shoes) {
nike_shoes->Message();
}
auto anta_shoes = ShoesFactory::Instance().Create("anta", 2);
if (nike_shoes) {
anta_shoes->Message();
}
auto benz_car = CarFactory::Instance().Create("benz", 1, "small");
if (nike_shoes) {
benz_car->Message();
}
auto audi_car = CarFactory::Instance().Create("audi", 2, "big");
if (nike_shoes) {
audi_car->Message();
}
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(test)
set(CMAKE_CXX_STANDARD 11)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_executable(test main.cc factory.h register.h shoes.h nike.cc anta.cc car.h benz.cc audi.cc)
输出
1 Nike shoes !
2 Anta shoes !
1 small Benz car !
2 big Audi car !