在c / c ++中使用变量作为对象名的方法

时间:2011-08-03 08:39:26

标签: c++ c compiler-construction

出于好奇:有没有办法在c ++中使用变量作为对象名?

一些事情:

char a[] = "testme\0";
*a *vr = new *a();

如果您要编写c / c ++编译器,您将如何实现这样的事情?

我知道他们在zend引擎中实现了这个功能,但懒得查找它。

也许你们中的一些人可以让我高兴:)

4 个答案:

答案 0 :(得分:6)

如果你要找的是这样的话

<?php
$className = "ClassName";
$instance = new $className();
?>

这在C ++中是不可能的。这失败的原因有很多,其中一个原因是C ++在运行时不再对类的名称了解太多(仅在调试模式下)如果有人想编写一个允许这样的东西的编译器,就有必要保留一个C ++编译器在编译和链接期间只需要的大量信息。改变这种情况会创造一种新语言。

如果要根据仅在运行时可用的信息动态创建类,在C ++中,您很可能会使用Creational Design Patterns中的一些。

修改

PHP是一种语言,C ++是一种非常不同的语言。现在16M可能不是那么多,对于一个C ++程序员来说,一些程序在k范围内,这是一个完整的世界。没有人想用他的C ++应用程序发布一个完整的编译器,以便能够获得所有的动态功能(据我所知,如果你想要真正动态的运行时代码创建,那么PHP也只能以有限的方式实现,请看一下Ruby或Python)。 C ++(作为所有语言)具有某种哲学,并且在字符串中按名称创建对象并不适合它。无论如何,这个功能本身毫无用处,并不能证明实现它所需的开销是合理的。这很可能在没有添加运行时编译的情况下完成,但即使是单独存储名称所需的额外千字节在C ++世界中也没有意义。并且C ++是严格类型的,这个功能必须确保,类型检查不会中断。

答案 1 :(得分:4)

在C和C ++中,标识符名称与PHP中的名称不同。

PHP是一种动态语言,并且(至少在概念上)在解释的上下文中运行。标识符名称在运行时出现,可以通过PHP的反射功能进行检查,您可以使用字符串按名称等引用函数,变量,全局变量和对象属性.PHP标识符是实际的语义实体。

在C ++中,标识符在运行时丢失(再次,从概念上讲)。您可以在源代码中使用它们来标识变量,函数,类等,但编译器会将它们转换为内存地址或文字值,甚至可以完全优化它们。标识符名称通常不存在于已编译的二进制文件中(除非您指示编译器包含调试符号),并且无法在运行时检查它们。即使使用RTTI,您可以获得的最佳数字是识别类型的任意数字;你可以比较它们的平等性,但你不能得到这个名字。

因此,如果要在C ++中的运行时将字符串转换为标识符名称,则必须手动执行映射。 std::map可以为此提供很好的帮助 - 你把它交给一个字符串,它会给你一个价值。这不能直接用于类名;对于这些,您需要实现某种工厂方法。一个很好的解决方案是为每种类型提供一个包装函数,然后使用std::map将类名映射到相应的包装器。类似的东西:

map<string, FoobarFactoryMethod> factory_map;

Foobar* FooFactory() { return new Foo(); }
Foobar* BarFactory() { return new Bar(); }
Foobar* BazFactory() { return new Baz(); }

void fill_map() {
    factory_map["Foo"] = FooFactory;
    factory_map["Bar"] = BarFactory;
    factory_map["Baz"] = BazFactory;
}

// and then later:
Foobar* f = factory_map[classname]();

答案 2 :(得分:0)

为什么你甚至想拥有这个功能?你最有可能滥用OOP。每当我的需求遇到像这样的硬语言障碍时,我最终会做以下其中一项:

  • 重新思考问题的解决方案,以便更好地适应OOP
  • 为您的问题创建DSL(特定于域的语言)
  • 为此部分问题创建代码生成器
  • 选择更适合您问题的语言

  • 上述

  • 的组合

答案 3 :(得分:-1)

我认为使用接口和工厂模式可以最好地完成您想要做的事情。