Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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++ 面向对象设计播放器和AI控制单元。动态演员?_C++ - Fatal编程技术网

C++ 面向对象设计播放器和AI控制单元。动态演员?

C++ 面向对象设计播放器和AI控制单元。动态演员?,c++,C++,假设我有一个演员类型,它可以是我游戏级别上任何可放置的对象。 我还有一个单元,它是演员的一个子类。一个单位可以是玩家或AI控制的英雄 该单位也有两个儿童班:玩家(玩家)和英雄(AI控制单位)。 在单位类中,玩家和英雄都需要移动信息、旋转和其他常规设置。在子类中,AI将具有与玩家不同且更多的功能 现在我面临着以下问题: 函数只接受Actor作为参数(例如,OnOverlap(Actor A*)) 但是OnOverlap()只有在它是一个单位类(英雄或玩家)时才应该做一些事情。 因此,我需要从C++

假设我有一个演员类型,它可以是我游戏级别上任何可放置的对象。 我还有一个单元,它是演员的一个子类。一个单位可以是玩家或AI控制的英雄

该单位也有两个儿童班:玩家(玩家)和英雄(AI控制单位)。 在单位类中,玩家和英雄都需要移动信息、旋转和其他常规设置。在子类中,AI将具有与玩家不同且更多的功能

现在我面临着以下问题:

函数只接受Actor作为参数(例如,
OnOverlap(Actor A*)
) 但是
OnOverlap()
只有在它是一个单位类(英雄或玩家)时才应该做一些事情。 因此,我需要从C++中的java中的代码< >代码>实例> <代码>。 一种解决方法是使用
dynamic\u cast
,但我不确定这对性能是否是个好主意。或者使用虚拟,但当英雄比玩家有更多的功能时,这将不起作用

或者我应该尝试一种全新的OOP设计吗?

这种技术被调用,检查动态转换的输出是否为NULL是一种有效的实现


另一种方法是
#包括
并使用
typeid(*a).name()
来获取a的类型的字符串名。

我想说
动态转换是。这本身并不一定是坏的,但这表明您的设计可能出了问题

OOP中的一个重要概念是多态性:即对象的行为因其类型而异,并且这种行为是封装的,隐藏在接口后面。如果明确检查对象的类型以更改要应用于该对象的逻辑,则违反了多态性

现在虚拟方法也不是很好,它们确实会产生运行时成本,有时会给表带来太多的复杂性。C++使<代码>虚拟<代码>方法异常,而不是默认,我相信这些原因。

您应该知道,虚拟方法只是一种多态性,称为动态多态性。根据对运行时影响较小的类型,还有另一种方法可以获得不同的行为:静态多态性。但这在复杂性方面并没有真正的帮助


现在,在这种情况下,你真正应该做的是分别对待不同的事情。您可能希望将此
OnOverlap()
方法用于
Units
,原因是:假设您仅对
Units
执行碰撞检查,而不是对所有
参与者进行碰撞检查。然后维护一个单独的
单元列表
,并在
单元
类中将该
方法设置为非虚拟。用这种方式思考通常是关键。

使用
动态\u cast
的需要通常(尽管不总是)是存在设计缺陷的标志。在这种情况下,我想你会的

如果不对您描述的体系结构的总体设计作进一步的评论,我会说使用虚拟方法是正确的方法。Have
OnOverlap
获取它的actor并调用actor上的
OnOverlap
方法,可能给它一个指向执行初始
OnOverlap
方法的对象的指针(从您的问题中不清楚这是什么(*))

OnOverlapped
本身是虚拟的。这允许您在演员单元的情况下“做正确的事情”,但在其他地方不做任何事情或其他默认行为。在这种情况下,这意味着您只能使用
Actor
的公共API,这是正确的。您必须将任何需要
Player
附加方法的内容移动到
Player
OnOverlapped
实现中。如果你真的认为由于某种原因你不能做到这一点,你也许应该在更高的层次上考虑另一种设计(可能需要编辑你的问题来提供更多关于你的体系结构的细节)。 (*)我最初读到你的问题时,我觉得
OnOverlap
已经不是
Actor
的一种方法;这是无关的事情的一部分。如果它是
Actor
的一部分,您可能会对名为的模式感兴趣,该模式可用于此类“冲突处理”类型的问题,也是一种使用动态调度(虚拟)的技术

这些函数由我的引擎预定义,其中参数必须 但是父函数“Actor”。因此,如果有演员与 网格,则调用该函数。在这种情况下,我看不到其他的 解决方案,而不是让Actor对象的实例知道其 一个仅仅是其他东西的玩家

Actor基类中的一个简单虚函数可以是noop。在单位类中覆盖它,如果需要的话,在英雄和玩家中更加专门化它。非单位参与者将调用空方法。比RTTI和成语实例更干净


有一个期望被专门化的子体覆盖的默认基本实现是可以的。这就是抽象基类的要点,但在本例中,您提供的是一个默认实现,它什么也不做。这样做的目的是发送“DoCollision”消息(C++中的一个虚拟函数)。您不关心哪个类处理它或如何处理它。只要对象具有DoCollision编译时“接口”,并且您正确地调度了它。

使用虚拟,这就是它的用途。我不明白你的逻辑,如果英雄比pkayer有更多的功能,它“不会工作”。在OOP中,有时您将使用虚拟,有时(希望很少)您必须向下转换,使用
dynamic\u cast
my engine实际上提供了一个“GetClass”方法:if(unit->GetClass()->IsChildOf(APlayerCharacter::StaticClass())但我仍然对其他解决方案感到好奇:>目前OnOverlap函数用于网格。这些功能是由我的引擎预定义的
void X::OnOverlap (Actor * actor) {
  actor->OnOverlapped(this);
}