有没有一种方法可以在不定义c++基类的情况下创建工厂

Is there a way to make a factory without defining a base class in c++?

本文关键字:c++ 定义 基类 工厂 创建 情况下 一种 方法 有没有      更新时间:2023-10-16

我使用Qt,有一件事困扰着我,那就是我必须使用QObject才能使用qRegisterMetaType。我尝试自己实现工厂方法并取得了成功,但我仍然需要使用抽象类。

是否可以在不定义基类(在本例中为对象)的情况下做同样的事情?

工作代码:

#include <iostream>
#include <string>
#include <map>
#include <typeinfo>
#include <functional>
class object
{
    public:
    virtual ~object(){}
    virtual std::string to_string() = 0;
};
class SomeObject : public object
{
    public:
    SomeObject(){}
    virtual ~SomeObject(){}
    virtual std::string to_string()
    {
        return "I am a type of SomeObject";
    } 
};
class SomeOtherObject : public object
{
    public:
    SomeOtherObject(){}
    virtual ~SomeOtherObject(){}
    virtual std::string to_string()
    {
        return "I am a type of SomeOtherObject";
    } 
};
std::map<std::string, std::function<object*()>> types;
template<typename O>
inline
static void register_type(const std::string & name)
{
    types[name] = [](){ return new O; };
}
static object * get_object(const std::string & object_name )
{
    return types[object_name]();
}
int main()
{
    register_type<SomeObject>("SomeObject");
    register_type<SomeOtherObject>("SomeOtherObject");
    object * some = get_object("SomeObject");
    object * some_other = get_object("SomeOtherObject");
    std::cout << "::" << some->to_string() << std::endl;
    std::cout << "::" << some_other->to_string() << std::endl;
    delete some;
    delete some_other;
    std::cout << "exit" << std::endl;
    return 0;
}

输出(需要-std=c++11):

::I am a type of SomeObject
::I am a type of SomeOtherObject 
exit

您可以使用需要一个间接级别的类模板,但它不需要SomeObjectSomeOtherObjectobject派生。

#include <iostream>
#include <string>
#include <map>
#include <typeinfo>
#include <functional>
class object
{
   public:
      virtual ~object(){}
      virtual std::string to_string() = 0;
};
template <typename RealObject>
class TemplateObject : public object
{
   public:
      TemplateObject() : ro_() {}
      virtual std::string to_string()
      {
         return ro_.to_string();
      } 
   private:
      RealObject ro_;
};
std::map<std::string, std::function<object*()>> types;
template<typename O>
inline
static void register_type(const std::string & name)
{
    types[name] = [](){ return new TemplateObject<O>(); };
}
static object * get_object(const std::string & object_name )
{
    return types[object_name]();
}
class SomeObject
{
    public:
    SomeObject(){}
    ~SomeObject(){}
    std::string to_string()
    {
        return "I am a type of SomeObject";
    } 
};
class SomeOtherObject
{
    public:
    SomeOtherObject(){}
    ~SomeOtherObject(){}
    std::string to_string()
    {
        return "I am a type of SomeOtherObject";
    } 
};
int main()
{
    register_type<SomeObject>("SomeObject");
    register_type<SomeOtherObject>("SomeOtherObject");
    object * some = get_object("SomeObject");
    object * some_other = get_object("SomeOtherObject");
    std::cout << "::" << some->to_string() << std::endl;
    std::cout << "::" << some_other->to_string() << std::endl;
    delete some;
    delete some_other;
    std::cout << "exit" << std::endl;
    return 0;
}

输出:

::I am a type of SomeObject
::I am a type of SomeOtherObject
exit

在Amit的帮助下,我找到了这个解决方案:

#include <iostream>
#include <string>
#include <map>
#include <typeinfo>
#include <functional>
class object
{
    public:
    virtual ~object(){}
    virtual std::string to_string() = 0;
};
class SomeObject : public object
{
    public:
    SomeObject(){}
    virtual ~SomeObject(){}
    virtual std::string to_string()
    {
        return "I am a type of SomeObject";
    } 
};
class SomeOtherObject : public object
{
    public:
    SomeOtherObject(){}
    virtual ~SomeOtherObject(){}
    virtual std::string to_string()
    {
        return "I am a type of SomeOtherObject";
    } 
};
std::map<std::string, std::function<void*()>> types;
template<typename O>
inline
static void register_type(const std::string & name)
{
    types[name] = [](){ return new O; };
}
static void * get_object(const std::string & object_name )
{
    return types[object_name]();
}
int main()
{
    register_type<SomeObject>("SomeObject");
    register_type<SomeOtherObject>("SomeOtherObject");
    object * some = (object*)get_object("SomeObject");
    object * some_other = (object*)get_object("SomeOtherObject");
    std::cout << "::" << some->to_string() << std::endl;
    std::cout << "::" << some_other->to_string() << std::endl;
    delete some;
    delete some_other;
    std::cout << "exit" << std::endl;
    return 0;
}