C++ 写个游戏引擎—(基础篇)11

今天先介绍 virtual 函数。先定义一个基类 Entity 并定义 GetName 公共方法,返回值为 Entity,然后再定义一个 Player 类,继承 Entity 类。定义一个私有属性 m_Name,并添加构造函数接受参数 name 来为 m_Name 赋值。同样也拥有同名 GetName 函数,函数返回 m_Name 值。

8207483-72f96c628ea01a9f

这里代码就不做过的解释了。

8207483-356d511a2d053921
8207483-998c8ad3ab0f021a
8207483-215ab86ff07ff0da
8207483-7103ab0bf16c8813

如下图中,利用向上转型(在 java 里这么叫),我们可以让类型 Entity 接受其子类 Player 的对象,然后调用对象的 GetName,查看输出结果,发现我们预期不同,这里输出 Entity 而不是 matthew。我们可以进一步验证

8207483-45e3878a89a28986
8207483-b84fdb58643d0ee1

为了更清晰分析这种现象,我们可以创建 printName 函数,让他接受 Entity 类型作为参数,然后调用传入对象的 getName 方法来输出信息。我们分别将 p 和 e 作为参数传入函数,运行程序,发现输出 Entity。

这里给大家解释一下原因,这是如果我们将 p 定义为 Entity 类型,他会先查找 Entity 类中是否有 getName 方法。如果有就调用。所以我们看到输出都是 Entity。如果我们想要传入 p 时,输出 matther 而不是 Entity 我们需要怎么做呢。

8207483-6db8581071197b34
8207483-4226a558659ffe0e
8207483-ed65c564a1818425

virtual 提供了解决方案,在 Entity 的 getName 方法前加上 virtual 关键字,表示如果子类用 override 复写这个方法,修改调用复写的方法而不是调用 Entity 的 getName 方法。

8207483-5817a4ba14c2443f
8207483-864903a7399e620a

Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

我们要在 c++ 中实现相同功能,看一看。我们将 Entity 类中的 GetName 方法声明,并不实现该方法,做法如下图。

8207483-028b0dde6f15863c

修改代码后,发现错误,必须将 Entity 修改为 Player 因为只有 Player 类中才实现了 GetName 方法。

8207483-d464f3e8805b81a3
8207483-3f07954fad06d271

我们写一个 print 方法接受某一个类的实例作为参数,然后调用该对象的 GetClassName 方法

8207483-b7b808c8c7c2e154

我们可以定义一个接口 Printable 来实现我们的期望,需要注意的是在 c++ 中并没有像 java 中的 interface 关键字来定义接口,我们需要使用 class 来定义一个接口

8207483-95aa53930b3b5f55

让 print 方法接受 Printable 类型的对象作为参数。

8207483-4227f80a3db4661e

Entity 可以继承 Printable 这个类(接口)并在 Entity 和 Player 中重新 GetClassName 方法。

8207483-7ddb235fd25c3270
8207483-ed3ced0e1c1065f6
8207483-90abdee2797371cf
8207483-f434582a8d69c203
8207483-b260d69fcc5f4a0e
8207483-0169edf64371ad30

猜你喜欢

转载自blog.csdn.net/weixin_34066347/article/details/86797419
今日推荐