简体   繁体   English

在此示例中,dynamic_cast是解决方案吗?

[英]In this example, is dynamic_cast the solution?

The Problem 问题

I have different classes that are some sort of Manager , ie, they manage classes called Entities . 我有一些类似于Manager ,即它们管理称为Entities类。 There may be a lot of different Manager classes, but they all have one method in common, addEntity . 可能有很多不同的Manager类,但是它们共有一个共同的方法addEntity

Example: 例:

class AManager
{
    addEntity(Entity e, AContract contract);
}

class BManager
{
    addEntity(Entity, BContract contract);
}

 ...

Now I want at any given time have the possibility to add a Entity to any of this classes, given that I also give the classe's Contract (class with only data) as well. 现在,我希望在任何给定时间都可以将一个Entity添加到任何此类中,因为我也要给该类别的Contract (仅包含数据的类别)。 Note that up until now there is no kind of inheritance whatsoever. 请注意,到目前为止,还没有任何继承。

This classes should not be directly accessible to the user as well, so they are accessible from another class called ComponentManager , which stores references to this XManagers . 用户也不应直接访问此类,因此可以从另一个名为ComponentManager类访问该类,该类存储对此XManagers引用。 So in the class ComponentManager I want to add this method. 因此,在类ComponentManager我想添加此方法。

enum class ManagerType
{
    A, B, // ...
}

class ComponentManager
{
public:
    addEntityToManager(Entity e, XContract, ManagerType type);
private:
    // References to all manager classes
} 

The reason I want to do that, is that it is not practical to create one different method for each Manager ( addEntityToXManager ), because there may be a lot of them. 我想要这样做的原因是,为每个ManageraddEntityToXManager )创建一个不同的方法是不切实际的,因为其中可能有很多方法。 So it would be nice to just pass an Enum , and the correct method is called for me. 因此,仅传递Enum会很不错,并且为我调用了正确的方法。

One solution that I though of was using dynamic_cast , where each XContract inherits from a BaseContract class: 我的一个解决方案是使用dynamic_cast ,其中每个XContract继承自BaseContract类:

class AManager
{
    addEntity(Entity e, BaseContract contract);
}

class BManager
{
    addEntity(Entity, BaseContract contract);
}

Now I could pass the contract to any of this classes, so I think I would have to use dynamic_cast to the correct contract so I can work with them. 现在,我可以将合同传递给任何此类,因此,我认为我必须使用dynamic_cast才能使用正确的合同,这样我才能使用它们。

  • Is this a good solution? 这是一个好的解决方案吗?

Somehow this seems to me more like a hack than an actual solution, because any kind of Contract would be accepted. 在某种程度上,这在我看来更像是一种hack,而不是实际的解决方案,因为可以接受任何形式的Contract

如果我正确地理解了您的问题,就像您有多种管理器类型,而这些用户都不知道下层管理器类,那么为什么不使用工厂方法设计模式以便您可以轻松地插入新管理器呢?

I'm not sure if dynamic_cast is a good idea and how you decide what type to cast to? 我不确定dynamic_cast是否是个好主意,以及如何决定要转换为哪种类型? you can try template the method addEntityToManager and addEntity , for example something like this: 您可以尝试使用方法方法addEntityToManageraddEntity ,例如:

class   ContractA
{
public:
  std::string add()
  {
    return std::string("adding to contract A");
  }
};

class   ContractB
{
public:
  std::string add()
  {
    return std::string("adding to contract B");
  }
};

class   ManagerA
{
public:
  template<typename T>
  void  addEntity(T contract)
  {
    std::cout << "Manager A " << contract.add() << std::endl;
  }
};

class   ManagerB
{
public:
  template<typename T>
  void  addEntity(T contract)
  {
    std::cout << "Manager B " << contract.add() << std::endl;
  }
};

class   ComponentManager
{
public:
  template<typename T, typename U>
  void  addEntityToManager(T contract, U manager)
  {
    manager.addEntity(contract);
  }
};

and this test, 这个测试

int     main()
{
  ManagerA manA;
  ManagerB manB;
  ContractA contA;
  ContractB contB;
  ComponentManager compM;

  compM.addEntityToManager(contA, manA);
  compM.addEntityToManager(contA, manB);
  compM.addEntityToManager(contB, manA);
  compM.addEntityToManager(contB, manB);

  return 0;
}

will produce output: 将产生输出:

Manager A adding to contract A
Manager B adding to contract A
Manager A adding to contract B
Manager B adding to contract B

you can add template specializations where is needed :) 您可以在需要的地方添加模板专业化:)

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

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