在这个例子中,dynamic_cast是解决方案吗?

时间:2015-12-12 01:48:13

标签: c++ dynamic-cast

问题

我有不同的类Manager,即他们管理名为Entities的类。可能有很多不同的Manager类,但它们都有一个共同的方法,addEntity

示例:

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

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

 ...

现在我希望在任何给定的时间都可以为这些类添加Entity,因为我也给了classe的Contract(只有数据的类)。请注意,到目前为止,没有任何类型的继承。

这些类也不应该直接被用户访问,因此可以从另一个名为ComponentManager的类访问它们,该类存储对此XManagers的引用。所以在课程ComponentManager中我想添加此方法。

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

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

我想这样做的原因是,为每个ManageraddEntityToXManager)创建一个不同的方法是不切实际的,因为可能有很多方法。所以传递Enum会很好,并为我调用正确的方法。

我使用dynamic_cast的一个解决方案,其中每个XContract都继承自BaseContract类:

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

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

现在我可以将合同传递给任何一个类,所以我认为我必须使用dynamic_cast来签订正确的合同,以便我可以使用它们。

  • 这是一个很好的解决方案吗?

在某种程度上,这似乎更像是一个黑客而不是一个实际的解决方案,因为任何类型的Contract都会被接受。

2 个答案:

答案 0 :(得分:0)

如果我正确理解你的问题,就像你有多个管理者类型,并且那些用户与下层管理器类无关,那么为什么不使用工厂方法设计模式以便你可以轻松地插入新管理器?

答案 1 :(得分:0)

我不确定dynamic_cast是否是一个好主意以及您如何决定要投放到哪种类型?您可以尝试模拟方法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);
  }
};

和这个测试,

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

将产生输出:

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

您可以在需要的地方添加模板专业化:)