工厂类实现问题

Factory class implementation problems

本文关键字:问题 实现 工厂      更新时间:2023-10-16

我基于下面的文章实现了一个工厂类。

然而,我有一个问题,我认为这与编译器优化有关。

我有一个类的层次结构,其中类Node(在Node.h/Node.cpp中)是基类,例如,BuildingLot(在BuildingLot.h/BuildingLot.cpp中)是一个子类。

在这两个被声明为静态的源文件中,我都有一个Registor类。

Node.cpp:

static Registrar<Node> _registrar(“Node”);

BuildingLot.cpp:

static Registrar<BuildingLot> _registrar(“BuildingLot”);

如果我尝试使用Factory,它非常适合Node类。I、 但是,必须首先创建BuildingLot的实例才能在工厂中注册。

在单元测试中,我有:

NodePtr node = Factory::Instance()->Create(“Node”);
NodePtr bl = Factory::Instance()->Create(“BuildingLot”);

bl总是nullptr。Registrar构造函数永远不会被执行,因此Factory类永远不会知道BuildingLot类。如果我这样做:

BuildingLot b;
NodePtr node = Factory::Instance()->Create(“Node”);
NodePtr bl = Factory::Instance()->Create(“BuildingLot”);

然后一切都好了。注册官被召集,工厂创建了一个建筑地块。

我认为,由于第一个例子中没有使用BuildingLot,编译器进行了优化,甚至没有编译BuildingLot.cpp。

这可能吗?我该如何解决这个问题?

编辑:Registrar类实际上是一个模板类。我只是忘了插入模板参数。

这是我能做的最简单的代码。我希望我没有遗漏任何内容。如果我取消注释main()中的第一行,那么一切都可以。

NodeFactory.h:

class NodeFactory{
private:
    /// Map of factory functions
    std::map<std::string, std::function<std::shared_ptr<Node>(void)>> mFactoryFunctions;
public:
     /// Get Singleton
    static NodeFactory* Instance();
    /// Register Function.
    void Register(const std::string &name, std::function<std::shared_ptr<Node>(void)> factoryFunction);
    /// Factory Function.
    std::shared_ptr<Node> Create(const std::string &name);
};

NodeFactory.cpp:

/**
 * Get Singleton
 */
NodeFactory* NodeFactory::Instance(){
    static NodeFactory factory;
    return &factory;
}
void NodeFactory::Register(const std::string &name, std::function<std::shared_ptr<Node>(void)> factoryFunction){
    mFactoryFunctions[name] = factoryFunction;
}
std::shared_ptr<Node> NodeFactory::Create(const std::string &name){
    if(mFactoryFunctions.find(name) == mFactoryFunctions.end())
        return nullptr;
    std::shared_ptr<Node> n = mFactoryFunctions[name]();
    return n;
}

注册商:

#define REGISTER_NODE_TYPE(NODE_TYPE) static NodeRegistrar<NODE_TYPE> _registrar(#NODE_TYPE);
template<class T>
class NodeRegistrar{
private:
public:
    NodeRegistrar(const std::string &name){
        NodeFactory::Instance()->Register(name,
                                          [](void) -> std::shared_ptr<T> { return std::make_shared<T>(); }
                                          );
    }
};

节点.h:

class Node{
private:        
    /// The node ID.
    NodeID mID;
public:
    /* ****************************
     * Construction & Destruction *
     * ***************************/
    Node();
    Node(const NodeID &nodeID);
    virtual ~Node();
};

Node.cpp:

REGISTER_NODE_TYPE(Node);
Node::Node(){
    mID = -1;
}
Node::Node(const NodeID &nodeID){
    mID = nodeID;
}
Node::~Node(){
}

建筑标段h:

class BuildingLot : public Node{
public:
    BuildingLot();
    BuildingLot(const NodeID &nodeID);
    virtual ~BuildingLot();
};

BuildingLot.cpp:

REGISTER_NODE_TYPE(BuildingLot);
BuildingLot::BuildingLot(){
}
BuildingLot::BuildingLot(const NodeID &nodeID):Node(nodeID){
}
BuildingLot::~BuildingLot(){
}

main.cpp:

int main(int argc, const char * argv[]){   
// BuildingLot bl; // if I uncomment this, then it works
std::shared_ptr<Node> node = NodeFactory::Instance()->Create("Node");
std::shared_ptr<Node> buildingLot = NodeFactory::Instance()->Create("BuildingLot");
if(node == nullptr)
    std::cout << "node is nullptr" << std::endl;
if(buildingLot == nullptr)
    std::cout << "buildingLot is nullptr" << std::endl;
return 0;

}

最后,我选择在工厂类中手动注册lambda创建者。如果创建并使用宏,并且代码行数完全相同,那么这非常简单。