如何将字符串变量视为实际代码?
Posted
技术标签:
【中文标题】如何将字符串变量视为实际代码?【英文标题】:How do I treat string variables as actual code? 【发布时间】:2014-02-07 16:56:01 【问题描述】:这可能不是很清楚。假设我有一个char *a = "reg"
。现在,我想编写一个函数,在读取a
的值时,实例化一个特定类的对象并将其命名为reg
。
例如,假设我有一个 class Register
和一个单独的函数 create(char *)
。我想要这样的东西:
void create(char *s) //s == "reg"
//what goes here?
Register reg; // <- this should be the result
它应该是可重复使用的:
void create(char *s) //s == "second"
//what goes here?
Register second; // <- this should be the result
我希望我已经说清楚了。本质上,我想将变量中的值视为单独的变量名。这在 C/C++ 中是否可行?如果没有,有什么类似的吗?我目前的解决方案是对字符串进行哈希处理,哈希表会将相关的 Register 对象存储在该位置,但我认为这是非常不必要的。
谢谢!
【问题讨论】:
如果您可以将该字符串用作某种地图的键,那将会很方便。你不同意吗? 您不能在 C++ 中执行此操作,因为它不支持必要程度的动态性。您要解决的实际问题是什么? 为什么?你为什么要让除了你这个程序员以外的任何人来决定你的变量是什么调用?您选择您的 var-names,但是一旦编译代码,名称就消失了(有点)......无论如何我都看不到重点,但要回答:带有hash
、char *
和 @ 的 HashTable 987654330@ 会员听起来是明智之举...
javascript 是适合您的语言,但我会提醒您,这个问题听起来很像您在问如何使用螺丝刀将板切成两半的问题,而您真正需要的是第一个地方是演习。 描述您尝试使用这种疯狂技术解决的业务问题。可能有比您想到的更好的解决方案。
@PeterM:我不一定指类——它也可以是基本数据类型或结构。
【参考方案1】:
变量名称是编译时工件。它们在运行时不存在。在 C++ 中创建动态命名的变量没有意义。你会怎么称呼它?
假设您有这个假设的create
函数,并编写了如下代码:
create("reg");
reg.value = 5;
这不会编译,因为编译器不知道第二行中reg
指的是什么。
C++ 没有任何方法可以在运行时查找 变量,因此在运行时创建 它们是行不通的。哈希表是解决此问题的正确解决方案。将对象存储在哈希表中并按名称查找。
【讨论】:
【参考方案2】:这是不可能的。 C++ 不提供在运行时处理代码的任何工具。鉴于典型 C++ 实现的性质(提前编译为机器代码,丢失有关源代码的所有信息),这甚至是遥不可及的。
【讨论】:
【参考方案3】:就像我在评论中所说: 重点是什么?变量名是编译器,但最重要的是 - 你,程序员应该关心的东西。编译应用程序后,变量名可以是任何名称......它可能会被破坏和无意义,这不再重要了。 您读/写代码,包括 var-names。编译完成后,由硬件来处理。
C 和 C++ 都没有 eval
函数
仅仅是因为:你只编译你需要的东西,eval
暗示稍后可能没有意义的输入,或者需要其他依赖项。
C/C++ 是提前编译的,eval 意味着在运行时进行评估。然后,C 进程将暗示:预处理、编译和链接字符串,使其仍然是当前进程的一部分...
即使有可能,eval
总是被认为是邪恶的,对于像 C 系列这样的旨在可靠运行并且通常用于时间关键操作的语言来说,这会加倍。适合这项工作的工具以及所有这些......
具有hash
、key
、Register
、collision
成员的对象的 HashTable 是明智的做法。反正开销也不大……
仍然觉得你需要这个?
查看大量的脚本语言。 Perl、Python……它们都更适合做这类事情
【讨论】:
【参考方案4】:如果您需要一些变量创建和查找,您可以:
按照其他人的建议使用其中一种脚本语言 您自己明确地进行查找。最简单的方法是使用映射,它将一个字符串映射到您的寄存器对象。然后你可以:std::map<const char*, Register*> table; Register* create(const char* name) Register* r = new Register(); table[name] = r; return r; Register* lookup(const char* name) return table[name]; void destroy(const char* name) delete table[name]; table.erase(name);
显然,每次您想要访问以这种方式创建的变量时,您都必须调用lookup
。
【讨论】:
以上是关于如何将字符串变量视为实际代码?的主要内容,如果未能解决你的问题,请参考以下文章