可以实例化C+中给定类型的对象+;? 我在java编程的时间太长了,我找到了回到C++的方法。我想编写一些代码,使给定的类(类型\信息或字符串中的名称)可以创建该类的实例。为了简单起见,我们假设它只需要调用默认构造函数。这在C++中是可能的,如果不是,将来它会出现在TR?

可以实例化C+中给定类型的对象+;? 我在java编程的时间太长了,我找到了回到C++的方法。我想编写一些代码,使给定的类(类型\信息或字符串中的名称)可以创建该类的实例。为了简单起见,我们假设它只需要调用默认构造函数。这在C++中是可能的,如果不是,将来它会出现在TR?,c++,c++11,C++,C++11,我已经找到了一种方法来做到这一点,但我希望有更“动态”的东西。对于我希望实例化的类(这本身就是一个问题,因为我想让配置来决定),我创建了一个单例工厂,其中包含一个静态创建的实例,该实例将自己注册到另一个类中。对于类Foo,还有一个FooFactory,它有一个静态的FooFactory实例,因此在程序启动时调用FooFactory构造函数,该构造函数将自己注册到另一个类中。然后,当我希望在运行时创建一个Foo时,我找到FooFactory并调用它来创建Foo实例。在C++中有什么更好的方法吗?我

我已经找到了一种方法来做到这一点,但我希望有更“动态”的东西。对于我希望实例化的类(这本身就是一个问题,因为我想让配置来决定),我创建了一个单例工厂,其中包含一个静态创建的实例,该实例将自己注册到另一个类中。对于类Foo,还有一个FooFactory,它有一个静态的FooFactory实例,因此在程序启动时调用FooFactory构造函数,该构造函数将自己注册到另一个类中。然后,当我希望在运行时创建一个Foo时,我找到FooFactory并调用它来创建Foo实例。在C++中有什么更好的方法吗?我猜我已经被Java/C中丰富的反射所宠坏了


上下文,我尝试将一些我在java世界中已经习惯的IOC容器概念应用到C++,希望我能尽可能地动态地做它,而不需要在我的应用程序中为每个其他类添加一个工厂类。

< p>你总是可以使用模板,虽然我不确定这是你所寻找的:

template <typename T>
T
instantiate ()
{
  return T ();
}
模板
T
实例化()
{
返回T();
}
或者在课堂上:

template <typename T>
class MyClass
{
  ...
};
模板
类MyClass
{
...
};

您可以始终使用模板,尽管我不确定这是否是您想要的:

template <typename T>
T
instantiate ()
{
  return T ();
}
模板
T
实例化()
{
返回T();
}
或者在课堂上:

template <typename T>
class MyClass
{
  ...
};
模板
类MyClass
{
...
};

否。无法从类型名称转换为实际类型;rich reflection非常酷,但几乎总是有更好的方法。

不,没有办法从类型名称到实际类型;富反射是很酷的,但是几乎总是有更好的方法。

< P> >我没有检查过最后一次在C++中的“var”或“动态”(虽然那是前一段时间)。您可以使用(void*)指针,然后尝试相应地强制转换。此外,如果内存对我有用,C++确实有RTTI,这不是反射,但可以帮助识别运行时的类型。

< P> >我没有检查过C++中的“var”或“动态”(虽然那是前一段时间)。您可以使用(void*)指针,然后尝试相应地强制转换。此外,如果内存服务正确,C++确实有RTTI,它不是反射,而是可以帮助在运行时识别类型。

< P>欢迎C++(<)> /P> 创建这些对象需要一个
工厂
,这是正确的,但是每个文件可能不需要一个
工厂

实现这一点的典型方法是让所有可实例化类都从一个公共基类派生,我们称之为
base
,这样您就需要一个
工厂
,它每次都为您提供
std::unique\u ptr

有两种方法可以实现工厂的

  • 您可以使用
    Prototype
    模式,注册要创建的类的实例,在该实例上将调用
    clone
    函数
  • 您可以注册指向函数或函子的指针(或C++0x中的
    std::function
当然,困难在于动态注册这些条目。这通常在静态初始化期间的启动时完成

// OO-way
class Derived: public Base
{
public:
  virtual Derived* clone() const { return new Derived(*this); }
private:
};

// start-up...
namespace { Base* derived = GetFactory().register("Derived", new Derived); }

// ...or in main
int main(int argc, char* argv[])
{
  GetFactory().register("Derived", new Derived(argv[1]));
}

// Pointer to function
class Derived: public Base {};

// C++03
namespace {
  Base* makeDerived() { return new Derived; }
  Base* derived = GetFactory().register("Derived", makeDerived);
}

// C++0x
namespace {
  Base* derived = GetFactory().register("Derived", []() { return new Derived; });
}
启动方式的主要优点是,您可以在自己的文件中完美地定义
派生的
类,并将注册塞进其中,而其他文件不会受到您的更改的影响。这对于处理依赖项非常有用

另一方面,如果您希望创建的原型需要一些外部信息/参数,那么您将被迫使用初始化方法,其中最简单的方法是在获得必要的参数后,在
main
(或等效)中注册您的实例

快速说明:函数指针方法是最经济的(内存中)和最快的(执行中),但语法很奇怪

关于后续问题

是的,可以将类型传递给函数,但可能不是直接传递:

  • 如果所讨论的类型在编译时已知,则可以使用模板,不过需要一些时间来熟悉语法
  • 如果没有,那么您需要传递某种ID并使用工厂方法

如果您需要通过类似于Objult.class < /C> >,那么在我看来,您正在接近双DISPLAY用例,它将值得查看访问者模式。

欢迎在C++中:

创建这些对象需要一个
工厂
,这是正确的,但是每个文件可能不需要一个
工厂

实现这一点的典型方法是让所有可实例化类都从一个公共基类派生,我们称之为
base
,这样您就需要一个
工厂
,它每次都为您提供
std::unique\u ptr

有两种方法可以实现工厂的

  • 您可以使用
    Prototype
    模式,注册要创建的类的实例,在该实例上将调用
    clone
    函数
  • 您可以注册指向函数或函子的指针(或C++0x中的
    std::function
当然,困难在于动态注册这些条目。这通常在静态初始化期间的启动时完成

// OO-way
class Derived: public Base
{
public:
  virtual Derived* clone() const { return new Derived(*this); }
private:
};

// start-up...
namespace { Base* derived = GetFactory().register("Derived", new Derived); }

// ...or in main
int main(int argc, char* argv[])
{
  GetFactory().register("Derived", new Derived(argv[1]));
}

// Pointer to function
class Derived: public Base {};

// C++03
namespace {
  Base* makeDerived() { return new Derived; }
  Base* derived = GetFactory().register("Derived", makeDerived);
}

// C++0x
namespace {
  Base* derived = GetFactory().register("Derived", []() { return new Derived; });
}
启动方式的主要优点是,您可以在自己的文件中完美地定义
派生的