如何在 C++ 中实现元类?

发布于 2024-07-18 02:32:17 字数 134 浏览 4 评论 0原文

我已经阅读了一些关于什么是元类的内容,但我想知道它们是否可以在 C++ 中实现。

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

谢谢。

I've been reading a bit about what metaclasses are, but I would like to know if they can be achieved in C++.

I know that Qt library is using MetaObjects, but it uses an extension of C++ to achieve it. I want to know if it is possible directly in C++.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

鹿童谣 2024-07-25 02:32:17

如果元类的工作定义是“实例化本身就是类的语言实体”,那么泛型就是 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 类型的对象,程序也已完成。

If the working definition of metaclass is "a language entity whose instantiations are themselves classes," then generics are metaclasses in 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;
}

The use of Meta<double> in the antepenultimate line compels the compiler to instantiate the Meta<double> class; the sizeof operator operates upon Meta, thus demonstrating that this is not simply semantic sugar and that the class has been instantiated. The program is complete even though no objects of type Meta are instantiated.

我的鱼塘能养鲲 2024-07-25 02:32:17

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

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

但一般来说,常规元类提供的大部分功能都已经由 C++ 语言提供了; 只是以不同的形式。 实际上,您想要元对象的唯一原因是为了反射目的,在 C++ 中实现反射有不同的方法,如 本文档

除此之外,如果您确实使用 Objective-C 风格的元类系统,我不知道有任何库可以做到这一点,但很可能有。 另一方面,自己推出也不应该那么困难。

C++ Doesn't have built-in support for meta-classes (not in the Python/Objective-C way), however you can manually mimic the behavior of meta-classes. The basics are pretty simple, you create an extra class with a longer lifespan (Singleton, static object or the Construct On First Use Idiom) that is able to create and manipulate it's corresponding class. (In Objective-C the meta-class generally contains 'static' member variables, the memory allocation/deallocation routines et cetera).

What Qt has done is, they took the concept of meta-classes and modified it so that they can support some form of Reflection (and RTTI on systems that don't support it). Implementing this will require either a lot of macro magic or a custom compiler (such as they've chosen to use).

Generally though, most of the features a regular meta-class provides are already provided by the C++ language; just in a different form. And really, the only reason you'd want meta-objects would be for reflection purposes, there are different ways to implement reflection in C++ as outlined in this document.

Besides that, if you're really set on a Objective-C-style meta-class system, I'm not aware of any libraries that do that but there might very well be. On the other hand, rolling your own shouldn't be that difficult either.

无人接听 2024-07-25 02:32:17

Gamma 等人所著的《设计模式》一书中的几个模式与元类概念具有相似的特征。 例如,“策略”模式允许您在创建时自定义对象行为。 信封习语是另一个紧密匹配的习语。 不过,它们都不允许您自定义类的接口。

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

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

戴夫

Several of the patterns in the book "Design Patterns" by Gamma, et al have similar features to the metaclass concept. The "Strategy" pattern allows you to customize object behavior at creation time, for example. The letter-envelope idiom is another close match. Neither let you customize the interface to the class, though.

In COM, the IDispatch interface allows for dynamically adding methods/attributes to an object at runtime. It means giving up standard c++ method calls, though. Every call goes through the same method, which takes an index or string key into a user-maintaned method/property table and all parameters must be passed as an array of objects.

Using those two techniques you can get the flexibility of metaclasses, but it is a much harder slog thanks to having no syntactic goodness or runtime/compiler help.

Dave

梦在深巷 2024-07-25 02:32:17

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

无论如何,这取决于您是否想要带有方法的元类或仅带有数据的元类,数据类可以使用 Boost 构造(如 boost::any)来实现,如果您想要带有方法的类,您可以使用 boost::bind 来实现将方法绑定到对象,或者您可以使用单入口点接口(如 COM 对象)自行实现它们。

然而,“真正的”C++ 方法是使用泛型,因此它可以在编译时确定,以获得最佳性能。

老实说,我见过很少的系统,尽管我见过一些,真正需要运行时灵活性,在大多数情况下,对象在同一个类中诞生和消亡,或者至少足以将其生命周期的 95% 作为一个单一的对象来度过。他们从工厂出来后就上课。

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

It's possible to create meta-classes, however C++ is not about that, it's about statically compile-time based implementations, not runtime flexibility.

Anyways it depends if you want Meta-Classes with methods or just Meta-Classes with data, the Data classes can be implemented with Boost constructs like boost::any, and if you want Classes with methods, you can use boost::bind to bind methods to the object, or you can implement them on your own with a single-entry point interface like COM-objects.

However the "real" C++ way is to use generics so it can all be determined at compile-time, for best performance.

To be honest, I've seen very few systems, although I have seen some, that truly need runtime flexibility, in most cases objects are born and die the same class, or at least enough to spend 95% of their lifetime as a single class once they come out of their factory.

So in many situations one finds themselves paying too much for runtime meta-classes. Of course there is the school of thought that this provides better developer performance, but in many situations, each line of code will be run on hardware a few hundred million times more than the time it took to write it. So you can think about compile-time and runtime classes as paying up front or leasing for-ever. Personally I like to pay up front.

我的痛♀有谁懂 2024-07-25 02:32:17

恐怕不是……至少不是天生的。

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

在 C++ 中,类没有运行时表示。 它们的表现出现在虚拟表之类的东西中。 但在许多方面,它们的运行方式类似于 C 函数,所有 OOP 的功能几乎都是粘合代码。

话虽如此,您可能希望使用其他语言的元类来实现许多事物的 OOP 模式。 您还可以“模拟”您自己的对象系统。

Afraid not... At least not natively.

Having a metaclass would generally require that there would be a runtime object representing a class, as is the case in Java.

In C++, classes do not have a runtime representation. Their manifestations occur in things like the virtual table. But in many ways they operate like C functions with all the OOP functioning almost as a glue code.

That being said, there are OOP patterns for many things that you may want to implement with a metaclass in other languages. You could also "simulate" your own object system.

守望孤独 2024-07-25 02:32:17

您可能想看看这篇博文。

https://herbsutter.com/2017/07/26 /metaclasses-thoughts-on-generative-c/

Meta 类可能会进入 C++,但还需要一段时间。

You may want to take a look at this blog post.

https://herbsutter.com/2017/07/26/metaclasses-thoughts-on-generative-c/

It's possible that Meta classes will be making its way into C++, but it will be some time yet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文