简体   繁体   English

调用未知的构造函数(用于反射的替换)c ++

[英]Call a unknown constructor (Replacement for reflection) c++

I'm porting a networking api I made in java/as3 to c++. 我正在将在java / as3中制作的网络API移植到c ++。 I'm quite new to c++ so I'm not that familiar with all the tools that are available. 我对C ++还是很陌生,所以我对所有可用的工具都不熟悉。

I have a class called Packet. 我有一个叫做Packet的类。 In my java/as3 class that packet has 2 hashmaps, one for classToId and one for idToClass. 在我的java / as3类中,数据包具有2个哈希映射,一个用于classToId,一个用于idToClass。

Then I register a derived packet with an id and its class object. 然后,我使用ID及其类对象注册一个派生数据包。

When a packet is received I get its packet ID and then create a new packet with that ID. 接收到数据包后,我将获得其数据包ID,然后使用该ID创建一个新数据包。

In as3 code I then use: 然后在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;
    }

As you can see, reflection is used to call the constructor. 如您所见,反射用于调用构造函数。 In c++ however, I have no idea how I could create this. 但是在c ++中,我不知道如何创建它。 I can't use a static list of packets because this is a API class.(So this class will be extended in an application using this API) 我不能使用静态的数据包列表,因为这是一个API类。(因此该类将在使用此API的应用程序中扩展)

The typical solution is to have a factory function, which connects the ID to the actual class. 典型的解决方案是具有工厂功能,该功能将ID连接到实际的类。 Say we have a set of classes to deal with shapes: 假设我们有一组处理形状的类:

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;
}

An alternative, if you don't really know what class you want "until later" is to provide a function that creates the correct ID. 如果您真的不知道自己想要的类,则可以选择一种方法,该方法可以创建正确的ID。

So if you want to be able to EXTEND your shape system with user-defined shapes, you could do something like this: 因此,如果您希望能够使用用户定义的形状扩展形状系统,则可以执行以下操作:

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();
}

This still relies on the Shape being a common base-class. 这仍然依赖于Shape是通用的基类。 If that isn't true, I'm not sure how easy it is to solve this in a way that is easy to understand/explain, etc. 如果那不是真的,我不确定以一种易于理解/解释的方式来解决这个问题有多容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM