c++如何实现类名创建类对象(反射)

1. 适用场景


c++开发过程中使用工厂模式创建各种类对象的时候可能需要写一堆的’if-else’函数来根据传入的参数类型创建不同的类对象; 尤其是多态的情况下返回基类指针的情况. 例如:

class B -> class A // B继承A
class C -> class A // C继承A

A *Create(type) 
{
    if (type == B) return new (std::nothrow) B;
    if (type == C) return new (std::nothrow) C;
    return nullptr;
}

以上场景在开发中很常见, 但是如果继承关系复杂, 这样的代码需要不停修改代码, 不是很合理. 比较好的方式是实现类似:

B *p = static_cast(Create("B"));
C *p = static_cast(Create("C"));

这样的效果. 其实就是JAVA中的反射机制的体现, 实际c++本身是不支持的, 但是可以通过曲线救国的方式来实现.

2. 实现思路


核心: 通过回调函数来实现创建.
步骤: 1> 创建一个单例工厂类, 类中维护一个类名和创建对应类的回调函数的映射关系(map) 2> 需要创建的时候根据传入的类名参数查找对应的回调函数来创建类

3. 具体实现代码


main.cpp

#include "class_factory.h"

class CReflex
{
public:
    int RunTest()
    {
        std::cout << "Class Created. Perfect Running." << std::endl;
        return 0;
    }
};

SIM_OBJECT_CREATE_METHOD_REGISTER(CReflex);

int main(int argc, char **argv)
{
    CReflex *pReflex = static_cast(ClassFactory::GetInst().Create("CReflex"));
    return pReflex->RunTest();    
}

class_factory.h

#ifndef CLASS_FACTORY_H
#define CLASS_FACTORY_H

#include 
#include 
#include 

typedef void *(*CLASS_CREATE_FN)();

class ClassFactory
{
public:
    static ClassFactory &GetInst();    

public:
    void *Create(const std::string &className);
    void RegistClass(const std::string &className, CLASS_CREATE_FN fn);

private:
	ClassFactory() = default;
	~ClassFactory() = default;
	ClassFactory(const ClassFactory &) = delete;
	ClassFactory &operator=(const ClassFactory &) = delete;

private:
    std::unordered_map m_mpObjName2Method;
};

class ClassRegisterAction
{
public:
    ClassRegisterAction(const std::string &className, CLASS_CREATE_FN fn);
};

#define SIM_OBJECT_CREATE_METHOD_REGISTER(className) \
        className *ClassCreate##className() \
        { \
            return new (std::nothrow) className; \
        } \
        ClassRegisterAction g_ClassRegisterAction##className(#className, (CLASS_CREATE_FN)ClassCreate##className);

#endif // CLASS_FACTORY_H

class_factory.cpp

#include "class_factory.h"

/// Class ClassFactory
ClassFactory &ClassFactory::GetInst()
{
    static ClassFactory factoryInst;
    return factoryInst;
}

void *ClassFactory::Create(const std::string &className)
{
    auto it = m_mpObjName2Method.find(className);
    if (it == m_mpObjName2Method.end()) {
        return nullptr;
    } else {
        return it->second();
    }
}

void ClassFactory::RegistClass(const std::string &className, CLASS_CREATE_FN fn)
{
    m_mpObjName2Method[className] = fn;    
}

/// Class ClassRegisterAction
ClassRegisterAction::ClassRegisterAction(const std::string &className, CLASS_CREATE_FN fn)
{
    ClassFactory::GetInst().RegistClass(className, fn);  
}

你可能感兴趣的:(c++技术,c++编程思想,c++/qt设计模式,c++,反射,工厂,类名,创建类)