Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在执行外部操作时,如何避免使用动态_cast?_C++_Dynamic Cast - Fatal编程技术网

C++ 在执行外部操作时,如何避免使用动态_cast?

C++ 在执行外部操作时,如何避免使用动态_cast?,c++,dynamic-cast,C++,Dynamic Cast,动态施法是纯粹的邪恶。大家都知道。只有noob使用动态_cast.:) 这就是我读到的关于dynamic_cast的内容。关于stackoverflow的许多主题都说“在这种情况下使用虚拟函数” 我有一些反映对象功能的接口。比如说: class IRotatable { virtual void set_absolute_angle(float radians) =0; virtual void rotate_by(float radians) =0; }; class IMovabl

动态施法是纯粹的邪恶。大家都知道。只有noob使用动态_cast.:)

这就是我读到的关于dynamic_cast的内容。关于stackoverflow的许多主题都说“在这种情况下使用虚拟函数”

我有一些反映对象功能的接口。比如说:

class IRotatable
{
  virtual void set_absolute_angle(float radians) =0;
  virtual void rotate_by(float radians) =0;
};

class IMovable
{
  virtual void set_position(Position) =0;
};
以及一组可实现它们的类的基:

class Object
{
  virtual ~Object() {}
};
在GUI层中,我希望根据用户选择的对象实现的功能启用/禁用或显示/隐藏按钮:

Object *selected_object;
我会这样做(简化):

旋转的按钮。\u.enabled=(动态\u投射(选定的\u对象)!=nullptr);
(...)
无效执行旋转(浮动角度)
{
if(自动旋转=动态投影(选定对象))
{
可旋转->旋转(角度);
}
}
但正如其他(更有经验的)人所说,这显然是糟糕设计的证据

在这种情况下,什么是好的设计

不,我不想在我的
对象中有一堆虚拟函数。我希望能够添加实现它的新接口和新类(以及新按钮),而无需触摸
对象

另外,虚拟功能,如通过
Object
中的
get\u按钮
,对我来说似乎不太合适。我的
对象
完全不知道GUI、按钮之类的东西


get_type
这样返回一些枚举的函数也可以解决一个问题,但我不明白为什么RTTI的自实现替代应该比本地替代更好(好的,它会更快,但在这种情况下并不重要)。

您已经一针见血了:您试图从“不透明”数据库获取类型信息对象*类型。使用dynamic_cast只是一种达到目的的技巧。可以说,你的问题实际上是C++没有你想要的:好的类型信息。但这里有一些想法

首先,如果你打算做很多类似的事情,你可能会发现你实际上正在从典型的继承转移,你的程序可能更适合基于组件的设计模式,这在视频游戏中更常见。在那里,你经常在根目录下有一个不透明的游戏对象,你想知道它有什么“组件”。Unity就是这样做的,他们有很好的编辑器窗口,基于附加到游戏对象的组件;但C#也有很好的类型信息

其次,系统的其他部分可能知道对象的具体类型,并可以帮助构建可视化显示,从而使对象*不再成为瓶颈

第三,如果你真的使用了你所说的选项,我想你会发现拥有某种类型的类型id比使用dynamic_cast更有帮助,因为你可以构建表格来查找类型,比如说可视化构建器


此外,您还想知道为什么自卷类型info与RTTI相比?如果您非常关心性能,RTTI适用于所有类型,这意味着一切都可能受到冲击;自滚动选项允许选择加入(以复杂性为代价)。此外,如果您正在编写通过源代码等方式拉入的库,则无需将此推给其他人。

这将是一个很好的问题。如果不知道所选对象是什么,则无法回答此问题。从表面上看,你根本不需要强制转换。我在
selected\u object
上添加了一些基本信息。避免动态强制转换的一般方法是首先不要丢弃类型信息。您可能会发现访问者模式很有用。对于非常紧密耦合的类,它允许您完全避免强制转换,否则它允许您集中强制转换。但首先,也是最重要的是,认真思考如何更改您的设计,以避免丢掉所需的信息。例如,不要大量收集所有的东西,而是考虑两个或多个更受限制和直接有用的集合。这仍然是检查类是否在运行时实现特定接口的唯一方法。对界面进行动态转换并不是坏事。。。
button_that_rotates.enabled = (dynamic_cast<IRotatable*>(selected_object) != nullptr);

(...)

void execute_rotation(float angle)
{
  if(auto rotatable = dynamic_cast<IRotatable*>(selected_object))
  {
    rotatable->rotate_by(angle);
  }
}