2009-04-13 83 views
2

我一直在阅读一些关于元类的内容,但我想知道它们是否可以在C++中实现。如何在C++中实现元类?

我知道Qt库正在使用MetaObjects,但它使用C++的扩展来实现它。我想知道它是否可以直接在C++中使用。

谢谢。

回答

1

可以创建元类,但是C++并不是这样的,它是关于基于静态编译时的实现,而不是运行时的灵活性。

无论如何,这取决于你是否想要方法的Meta-Classes,或者只需要Meta-Classes与数据,Data类可以用Boost构造如boost :: any来实现,如果你想要方法的类,可以使用boost :: bind方法绑定到对象,或者你可以用COM-objects之类的单入口点接口自己实现它们。

然而,“真正的”C++方法是使用泛型,因此它可以在编译时确定,以获得最佳性能。老实说,虽然我见过很少的系统,但真正需要运行时的灵活性,在大多数情况下,对象是天生的,死于同一个类,或者至少足够花95%的系统一旦他们从工厂出来,他们终身成为一个班级。

所以在许多情况下,人们会发现自己为运行时元类付出太多。当然,有一种观点认为,这可以提供更好的开发人员性能,但在许多情况下,每行代码将在硬件上运行,比写它的时间多几亿倍。因此,您可以将编译时和运行时类考虑为付费或永久租用。我个人喜欢先付款。

3

Gamma等人在书籍“设计模式”中的几种模式与元类概念具有相似的特征。例如,“策略”模式允许您在创建时自定义对象行为。信封成语是另一个密切的匹配。尽管如此,也不要让你自定义该类的接口。

在COM中,IDispatch接口允许在运行时向对象动态添加方法/属性。这意味着放弃标准的C++方法调用。每次调用都会经历相同的方法,该方法将索引或字符串键引入用户维护的方法/属性表中,并且所有参数都必须作为对象数组传递。

使用这两种技术可以获得元类的灵活性,但是由于没有语法优势或运行时/编译器的帮助,这是一个更难的方法。

戴夫

1

不怕......至少不是天生的。

拥有一个元类通常需要有一个表示类的运行时对象,就像Java中的情况一样。

在C++中,类没有运行时表示。它们的表现发生在虚拟表格之类的事物中。但是在很多方面,它们都像C函数一样操作,所有的OOP几乎都以胶水代码的形式运行。

这就是说,有很多事情你可能想要用其他语言的元类来实现OOP模式。你也可以“模拟”你自己的对象系统。

3

如果元类的工作定义为“一个语言实体,其实例是自己班”,然后仿制药在C元类++:

#include <iostream> 
using namespace std; 

template <typename T> 
class Meta { 
public: 
    Meta(const T&init) : mData(init) {} 
// ... 
private: 
    T mData; 

}; 

int main(int, char **) { 
    cout << "The size of Meta<double> is " << sizeof(Meta<double>) << endl ; 
    return 0; 
} 

在倒数第三行中的双>使用元<的强迫编译器实例化Meta <双>类; sizeof操作符在Meta上运行,从而证明这不是简单的语义糖,并且类已经被实例化。即使没有实例化Meta类型的对象,程序也是完整的。

3

C++没有内置的对元类的支持(不是以Python/Objective-C方式),但是你可以手动模仿元类的行为。基础非常简单,您可以创建一个具有较长使用寿命的额外类(单例,静态对象或Construct On First Use Idiom),该类可以创建和操作相应的类。 (在Objective-C中,元类通常包含'静态'成员变量,内存分配/释放例程等等)。

Qt做了什么,他们采用了元类的概念并对其进行了修改,以便它们可以支持某种形式的Reflection(以及不支持它的系统上的RTTI)。实现这将需要大量的宏魔法或自定义编译器(比如他们已经选择使用)。

通常,C++语言已经提供了大部分常规元类提供的功能,只是以不同的形式。实际上,想要元对象的唯一原因是出于反射的目的,如this document中概述的那样,在C++中实现反射有不同的方法。除此之外,如果你真的设置了一个Objective-C风格的元类系统,我不知道有任何库可以这样做,但很可能。另一方面,滚动你自己也不应该那么困难。