2009-07-10 84 views
0

我在想我的想法。我想问你是否知道任何与此相关的图书馆或文章。或者你可以告诉我这是一个愚蠢的想法,为什么。Dynamic C++

我有一个类,我想在运行时动态添加方法/属性。我非常了解使用复合/命令设计模式和使用嵌入式脚本语言来完成我所说的技术。我只是在探索这个想法。没必要说这是个好主意。

class Dynamic 
{ 
public: 
    typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap; 

    void addMethod(const std::string& name, boost::function<void (Dynamic&)> func) { 
     funcMap_[name] = func; 
    } 

    void operator[](const std::string& name) { 
     FuncMap::iterator funcItr = funcMap_.find(name); 
     if (funcItr != funcMap_.end()) { 
      funcItr->second(*this); 
     } 
    } 

private: 
    FuncMap funcMap_; 
}; 

void f(Dynamic& self) { 
    doStuffWithDynamic(self); 
} 

int main() 
{ 
    Dynamic dyn; 
    dyn.addMethod("f", boost::bind(&f, _1)); 
    dyn["f"]; // invoke f 
} 

的想法是,我可以重新绑定名称“F”在运行时的任何功能。我知道字符串查找和boost :: function与raw函数指针的性能问题。通过一些艰苦的工作和不可移植的黑客攻击,我认为我可以让性能问题变得不那么痛苦。

用同一种技术,我可以有一个“v表”的名称查找办“运行期间继承”和调度函数调用的动态运行属性的基础。

如果只是想告诉我用Smalltalk或Objective-C的,我尊重这一点,但我爱我的C++,我与它坚持。

+1

这将是更好的,如果“操作符[](常量的std :: string&名称)”返回一个boost ::函数对象,以便使语法有点更自然的“DYN [” F“()”,这将允许参数和“函数指针”的可能性(这实际上只是boost :: function的实例 – 2009-07-10 20:32:18

+1

不要“爱你的C++”。使用最适合当前任务的语言*,而不是“ “爱”,或者你认识的唯一一个人 – jalf 2009-07-10 22:29:13

+1

我通常开车到拐角商店买牛奶,有时候我走路去买牛奶,走路不是因为我不懂驾驶或不懂驾驶比步行更快我这样做是出于同样的原因,我的数学极客朋友花了几天和几周的时间解决他的模拟器可以在几秒钟内给他答案的一个方程式,我这样做是为了练习。 人们看到我走路,并试图帮助告诉我,我应该开车,因为它更快。谢谢,但我正在走路。 – 2009-07-11 20:38:12

回答

0

我不认为有这个确切的事情库。

当然,你必须有这些功能在某种程度上预先写好的,所以它似乎有将做你想做的更简单的方法。例如,您可以只使用一种方法从您最喜欢的脚本语言中执行任意代码。这似乎是一个更简单的方法来做你想做的事情。

+0

这个想法是Dymanic类不会改变,并且在Dymanic被部署后可以实现新的函数f()。在不重新启动的过程中,我可以改变Dymanic的行为。 – 2009-07-10 21:07:06

2

我不认为改变C++来完成这项工作不是一个好主意。我建议使用另一种语言,比如Lisp或Perl或其他基本上是动态的语言,或者嵌入动态语言并使用它。

+0

实际上,编程语言Lua对于这类东西非常适用。但那不是重点。我正在探索在C++中动态运行时绑定的想法,而不是“我应该使用动态语言来解决我的问题”。 – 2009-07-10 21:22:20

+1

好吧,或许你应该探索“我应该用动态语言来解决我的问题”的想法;) – jalf 2009-07-10 22:27:16

+0

动态语言很好,但我所说的是C++看起来对我来说真的很没有吸引力,一种动态的语言。如果你真的感兴趣,一定要仔细研究一下。我发现有前途的,没有出路的方法的记录绝不是完美的(例如,我认为网络不太可能流行)。然而,只需要一些工作来获得一个有足够细节理解的连贯提案。 – 2009-07-13 14:28:25

8

你想要的是把C++改成非常不同的东西。 C++的(许多)目标之一是高效实现。对函数调用进行字符串查找(不管你实现它的程度如何),与普通的调用机制相比,效率不会很高。

基本上,我认为你正试图在不同语言的功能中使用shoehorn。在某种程度上,你可以使它工作,但是你正在创建没有其他人能够(或愿意)试图理解的C++代码。

如果你真的想在可以改变它的飞行物体语言写的,然后去找到这样的语言(有很多选择,我敢肯定)。试图将这种功能强加到C++中会导致你的问题。

请注意,我并不陌生,引进非C++概念到C++。我曾花费大量时间去除另一位工程师将基础对象系统引入C++项目的尝试(他喜欢容器'Object *'的想法,因此他让系统中的每个类都从他自己的'对象'类)。

引入外语概念几乎总是以两种方式严重结束:该概念与其他C++概念相冲突,并且无法像源语言那样工作,并且该概念倾向于打破其他某些内容C++。你最终失去了很多时间试图实现一些无法解决的问题。

我可以看到像这样的工作都很好,唯一的办法是,如果你实施了C++之上的新的语言,用Cfront样式的预编译。这样,你可以把一些体面的语法放到这个东西上,并消除你的一些问题。

+3

你说得对。他不如使用Python或类似的东西。 – 2009-07-10 21:07:13

+0

我完全不同意这个想法。我只想看看是否有人花更多时间在类似的想法上。 – 2009-07-10 21:13:28

0

我一直Visitor模式的思考。这允许您对访问对象(以及访问对象,认为这与您的问题看起来不相关)进行vtable查找。

并在运行时,你可以有一些变量,它指的是游客,并调用

Dynamic dynamic; 
DynamicVisitor * dv = ...; 
dynamic->Accept(dv); 
dv = ...; // something else 
dynamic->Accept(dv); 

的一点是,访问者对象有一个虚函数表,你说你想,你可以改变它的动态的价值,你说你想要的。 Accept基本上是“在编译时调用我不知道的东西的函数”。

1

你在做什么其实是Visitor pattern的变化。

编辑:顺便说一句,另一个方法是通过使用Lua中,因为语言让你在运行时添加的功能。 Objective-C++也是如此。

编辑2:其实你可以从FuncMap以及继承:

class Dynamic; 

typedef std::map<std::string, boost::function<void (Dynamic&)> > FuncMap; 

class Dynamic : public FuncMap 
{ 
public: 
}; 

void f(Dynamic& self) { 
    //doStuffWithDynamic(self); 
} 

int main() 
{ 
    Dynamic dyn; 
    dyn["f"] = boost::bind(&f, _1); 
    dyn["f"](dyn); // invoke f, however, 'dyn'param is awkward... 
    return 0; 
} 
0

我已经考虑之前也这样做。然而,基本上,你会在编写一个简单的虚拟机或解释器的途中(看看Lua或Topaz的消息来源,了解我的意思 - Topaz是一个在Parrot出现之前就已经死了的项目)。

但如果你打算是有意义的只是使用现有的虚拟机或解释这条路线。

1

如果我理解你正在努力达到的目标,似乎动态链接(即windowslinux中的动态加载库)将完成大部分尝试完成的任务。

也就是说,你可以在运行时,选择要执行的函数的名称(如DLL的名称),然后把它加载并执行。 COM的工作方式很多。或者甚至可以使用从该库导出的函数的名称来选择正确的函数(抛开C++名称修改问题)。

3

如果你实现了这个功能,即使是纯粹的库,然后大量使用它,你也会使用一种新的语言 - 一种语言丑陋,一种奇怪的运行时方法解析和不可靠的边界检查。

作为C/C++风格语法的粉丝,显然是动态方法调度的粉丝,您可能对C#4.0感兴趣,C#4.0现在处于Beta版,并且有dynamic关键字来准确地表示这种事情无缝混入正常的静态类型代码中。