【问题标题】:Call a unknown constructor (Replacement for reflection) c++调用未知构造函数(替换反射)c ++
【发布时间】:2015-02-07 23:47:38
【问题描述】:

我正在将我在 java/as3 中制作的网络 api 移植到 c++。我对 c++ 很陌生,所以我对所有可用的工具都不是很熟悉。

我有一个名为 Packet 的类。在我的 java/as3 类中,该数据包有 2 个哈希图,一个用于 classToId,一个用于 idToClass。

然后我用一个 id 和它的类对象注册一个派生数据包。

收到数据包后,我会获取其数据包 ID,然后使用该 ID 创建一个新数据包。

然后在 as3 代码中使用:

    public static function getNewPacket(id:int):Packet
    {
        try
        {
            var clazz:Class = getClassById[id];
            return (clazz == null ? null : Packet(new clazz()));
        }
        catch (e:Error)
        {
            trace("Skipping packet with id " + id + ": " + e.message);
        }
        return null;
    }

如你所见,反射是用来调用构造函数的。 但是,在 c++ 中,我不知道如何创建它。 我不能使用静态数据包列表,因为这是一个 API 类。(所以这个类将在使用这个 API 的应用程序中扩展)

【问题讨论】:

  • 底线——C++ 中没有reflection。您需要“跳出 Java 框架”思考才能提出解决方案。
  • 这就是我问 SO 的原因,我不知道可用于替代反射的工具。
  • Classes 上有哪些限制可以存储在getClassById 映射中?它们可以是任何具有无参数构造函数的类,还是必须是某个基类的子类——它是在您的应用程序中定义的基类,还是其他什么?或者是否有可接受的课程的简短列表?
  • 没有工具。您必须选择一个design pattern 或一组设计模式来实现您的目标。这不是 C++ 问题,而是程序设计以及如何完成的问题。 stackoverflow.com/questions/41453/…

标签: java c++ actionscript-3 reflection


【解决方案1】:

典型的解决方案是有一个工厂函数,它将 ID 连接到实际的类。假设我们有一组类来处理形状:

class Shape { ... };
class Square : public Shape { ... } ;
class Triangle  : public Shape { ... };

enum ShapeID { SquareID, TriangleID, ... }

Shape *shapeFactory(ShapeID id)
{
   switch(id) 
   {
      case SquareID:   return new Square;
      case TriangleID: return new Triangle;
       ...
   };
   return NULL;
}

如果您真的不知道“直到以后”想要什么类,另一种方法是提供一个创建正确 ID 的函数。

因此,如果您希望能够使用用户定义的形状来扩展您的形状系统,您可以执行以下操作:

typedef Shape* (*shapeCreatorFunc)();
... 

Shape* createStar()
{
   return new Star;
}

...
typedef std::map<ID, ShapeCreatorFunc> ShapeMap;
ShapeMap map;
...
map[SquareID] = createSquare;
map[TriangleID] = createTriangle;
map[StarID] = createStar;
....
ShapeMap::iterator it = map.find(id);
if (it != map.end())
{
   Shape *s = it.second();
}

这仍然依赖于Shape 作为一个通用的基类。如果这不是真的,我不确定以易于理解/解释等的方式解决这个问题有多容易。

【讨论】:

  • 谢谢伙计,正是我想要的。底部解决方案为我修复了它:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多