我用Java编程的时间太长了,找回了一些C ++的方法。我想编写一些给定类的代码(type_info或其在字符串中的名称)可以创建该类的实例。为简单起见,我们假设它只需要调用默认构造函数。这在C ++中是否可行,如果不是,它将来的TR?
我找到了一种方法来做到这一点,但我希望有一些更“动态”的东西。对于我希望实例化的类(这本身就是一个问题,因为我希望将该决定留给配置),我创建了一个单例工厂,其中包含一个静态创建的实例,该实例将自己注册到另一个类。例如。对于类Foo,还有一个具有静态FooFactory实例的FooFactory,因此在程序启动时会调用FooFactory构造函数,该构造函数将自己注册到另一个类。然后,当我希望在运行时创建一个Foo时,我找到了FooFactory并调用它来创建Foo实例。在C ++中做这件事有什么好处吗?我猜我刚刚被Java / C#中的反思所破坏。
对于上下文,我正在尝试将我在Java世界中习惯的一些IOC容器概念应用到C ++中,并希望我可以使它尽可能动态,而无需添加Factory类对于我申请中的其他课程。
答案 0 :(得分:0)
你可以随时使用模板,但我不确定这是你想要的:
template <typename T>
T
instantiate ()
{
return T ();
}
或者在课堂上:
template <typename T>
class MyClass
{
...
};
答案 1 :(得分:0)
欢迎使用C ++:)
您是正确的,您需要Factory
来创建这些对象,但每个文件可能不需要一个Factory
。
进行此操作的典型方法是让所有可实现的类派生自一个公共基类,我们将调用Base
,这样您就需要一个Factory
来提供std::unique_ptr<Base>
{1}}每次都给你。
有两种方法可以实现Factory
:
Prototype
模式,并注册要创建的类的实例,将在其上调用clone
函数。std::function<Base*()>
)当然,难点是动态注册这些条目。这通常在静态初始化期间启动时完成。
// 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; });
}
启动方式的主要优点是您可以在自己的文件中完美地定义Derived
类,将注册放在那里,并且没有其他文件受到您的更改的影响。这非常适合处理依赖项。
另一方面,如果您要创建的原型需要一些外部信息/参数,那么您将被迫使用初始化方法,最简单的方法是在main
中注册您的实例(或等效的) )一旦你有了必要的参数。
快速注意:指向函数方法的指针是最经济的(在内存中)和最快的(在执行中),但语法很奇怪......
关于后续问题。
是的,可以将类型传递给函数,但可能不是直接传递:
如果您需要传递类似于object.class
的内容,那么在我看来您正在接近双重调度用例,并且值得查看Visitor
模式。
答案 2 :(得分:-1)
没有。没有办法从类型名称到实际类型;丰富的反思非常酷,但几乎总有一种更好的方式。
答案 3 :(得分:-1)
上次我检查过C ++中没有“var”或“dynamic”这样的东西(虽然那是一个WHILE前)。您可以使用(void *)指针然后尝试相应地进行转换。此外,如果内存对我有用,C ++确实有RTTI,它不是反射,但可以帮助在运行时识别类型。