commit 2a17ecac501b54cf877c05f7a6ab5d3fc2cc38de Author: liamxin Date: Fri May 5 08:39:12 2023 +0800 init diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b2e9216 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.25) +project(c_base) + +set(CMAKE_CXX_STANDARD 17) + +add_executable(c_base main.cpp) diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..c0ddc01 --- /dev/null +++ b/main.cpp @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +// 自动注册实现 + +template +constexpr auto type_name() noexcept { + std::string_view name, prefix, suffix; +#ifdef __clang__ + name = __PRETTY_FUNCTION__; + prefix = "auto type_name() [T = "; + suffix = "]"; +#elif defined(__GNUC__) + name = __PRETTY_FUNCTION__; + prefix = "constexpr auto type_name() [with T = "; + suffix = "]"; +#elif defined(_MSC_VER) + name = __FUNCSIG__; + prefix = "auto __cdecl type_name<"; + suffix = ">(void) noexcept"; +#endif + name.remove_prefix(prefix.size()); + name.remove_suffix(suffix.size()); + return name; +} + +// 基类 +class Base { +public: + virtual const std::string_view className() const { + return "base"; + }; + + virtual ~Base() { + } + +}; + +using BFun = std::function; +using BMap = std::unordered_map; + +class Dic { +public: + + static void reg(std::string_view className, const BFun &fun) { + getMap().insert(std::make_pair(className, fun)); + } + + static BMap &getMap() { + static BMap bMap; + return bMap; + } +}; + +template +class BaseObj : public virtual Base { + +public: + + const std::string_view className() const override { + return allocator.className(); + } + + static const std::string_view getClassName() { + return allocator.className(); + } + +protected: + BaseObj() {}; + + ~BaseObj() override = default; + +private: + class Allocator { + public: + Allocator() { + registerClass(); + } + + const std::string_view &className() const { + static std::string_view class_name = type_name(); + return class_name; + } + + template + typename std::enable_if::value, + void>::type + registerClass() { + Dic::reg(className(), []() -> Base * { return new T(); }); + } + + template + typename std::enable_if::value, + void>::type + registerClass() { + + } + }; + + static Allocator allocator; +}; + +template +typename BaseObj::Allocator BaseObj::allocator; + + +// +class A : public BaseObj { +public: +}; + + +class B : public BaseObj { +public: +}; + + +// 工厂类 +class Factory { + +public: + static Base *create(const std::string & className) { + BMap map = Dic::getMap(); + auto iter = map.find(className); + if (iter != map.end()) { + return iter->second(); + } + return nullptr; + } +}; + + +int main() { + + auto aa = Factory::create("A"); + auto bb = Factory::create("B"); + + if (aa != nullptr) { + std::cout << aa->className() << std::endl; + } + + if (bb != nullptr) { + std::cout << bb->className() << std::endl; + } + + std::cout << "hello world!" << std::endl; + + return 0; +} \ No newline at end of file