在C ++中反射 [英] Reflection in C++

查看:143
本文介绍了在C ++中反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经工作了多年的Java。在那些年,我做了大量(或也许只是频繁)使用反射,并发现它有用和愉快。但8个月前我改变了我的工作,现在Java只是一个记忆,我得到了我的手上C ++。所以现在我想知道在C ++中是否有任何反射机制。我已经阅读关于RTTI,但我觉得这不是Java(或其他语言)的反射的力量。我开始认为,没有办法这样做在C + +。我错了吗?

解决方案

如果你正在寻找一个完全一般的方式来操纵对象在运行时,当你不知道他们你在本质上需要:


  1. 定义一个接口(抽象基类,所有纯虚方法,没有成员)


  2. 每个类必须从所有要实现的接口(可能在其他类中) ol>

    现在,假设 pFoo 包含 IFoo * 到一些对象 x (你不需要知道 x 的具体类型)。您可以通过说明

      if,查看此对象是否支持接口 IBar  (IBar * pBar = dynamic_cast (pFoo)){
    //在这里使用pBar做的东西
    pBar-> endWorldHunger();
    } else {
    //对象不支持该接口:正常降级
    pFoo-> grinStupidly();这个方法假设你在编译时知道所有相关的接口 strong> - 如果你不这样做,你将无法使用正常的C ++语法调用方法。但很难想象调用程序不知道需要什么接口的情况 - 如果你想通过交互式解释器暴露C ++对象,我可以想到的唯一情况是。即使这样,你可以设计一个(丑陋的,维护密集型的)方法来将这种方法引入到上述范例中,以便可以通过将方法的名称和参数指定为字符串来调用。



    需要考虑的另一个方面是对象创建。要完成这个而不知道具体的类型,你需要一个工厂函数,加上类的唯一标识符来指定你想要的具体类。可以安排课程在启动时向全球工厂注册,如C ++专家Herb Sutter所述 - 这避免维护一个巨大的切换语句,大大简化维护。可以使用单个工厂,但这意味着系统中的每个对象都必须实现一个接口(工厂将返回一个指针或对此接口类型的引用)。



    在一天结束时,你结束的是基本上(同构的) COM - dynamic_cast 执行与 QueryInterface(IID_IFoo)相同的工作,所有对象相当于 IUnknown


    I've been working for years with Java. During those years, I've made extensive (or maybe just frequent) use of reflection, and found it useful and enjoyable. But 8 months ago I changed my job, and now Java is just a memory, and I'm getting my hands on C++. So now I'm wondering if there is any reflection mechanism in C++. I've read about RTTI but I feel it's by no means the power of Java (or other languages) reflecion. I'm beggining to think that there's no way to do this in C++. Am I wrong?

    解决方案

    If you are looking for a totally general way to manipulate objects at runtime when you don't know their types at compile time in C++, you essentially need to:

    1. Define an interface (abstract base class with all pure virtual methods and no members) for each capability that a class might support.
    2. Each class must inherit virtually from all interfaces that it wants to implement (possibly among other classes).

    Now, suppose pFoo holds an interface pointer of type IFoo* to some object x (you don't need to know x's concrete type). You can see whether this object supports interface IBar by saying:

    if (IBar* pBar = dynamic_cast<IBar*>(pFoo)) {
        // Do stuff using pBar here
        pBar->endWorldHunger();
    } else {
        // Object doesn't support the interface: degrade gracefully
        pFoo->grinStupidly();
    }
    

    This approach assumes you know all relevant interfaces at compile time -- if you don't, you won't be able to use normal C++ syntax for calling methods anyway. But it's hard to imagine a situation where the calling program doesn't know what interfaces it needs -- about the only case I can think of would be if you want to expose C++ objects via an interactive interpreter. Even then, you can devise an (ugly, maintenance-intensive) way of shoehorning this into the above paradigm, so that methods can be called by specifying their names and arguments as strings.

    The other aspect to consider is object creation. To accomplish this without knowing concrete types, you'll need a factory function, plus unique identifiers for classes to specify which concrete class you want. It's possible to arrange for classes to register themselves with a global factory upon startup, as described here by C++ expert Herb Sutter -- this avoids maintaining a gigantic switch statement, considerably easing maintenance. It's possible to use a single factory, though this implies that there is a single interface that every object in your system must implement (the factory will return a pointer or reference to this interface type).

    At the end of the day, what you wind up with is basically (isomorphic to) COM -- dynamic_cast<IFoo*> does the same job as QueryInterface(IID_IFoo), and the base interface implemented by all objects is equivalent to IUnknown.

    这篇关于在C ++中反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆