" class"参数前的平均值?

时间:2016-12-24 09:34:18

标签: c++ syntax parameters unreal-engine4

虚幻引擎生成以下功能:

void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
    //stuff...
}

注意"类"参数类型之前的说明符。这是什么意思?

3 个答案:

答案 0 :(得分:8)

<强> 1。第一种可能性,如果之前未声明UInputComponent,则可能是forward declarations。所以

void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)

forward声明一个名为UInputComponent的类,参数InputComponent的类型为UInputComponent*

  

请注意,elaborated type specifier也可能引入一个新的类名,该类名称作为另一个声明的一部分出现,但仅限于   如果name lookup无法找到之前声明的相同类   名。

class U;
namespace ns{
    class Y f(class T p); // declares function ns::f and declares ns::T and ns::Y
    class U f(); // U refers to ::U
    Y* p; T* q; // can use pointers and references to T and Y
}

<强> 2。第二个possibility ,关键字class可能会用于消除歧义。

  

如果范围中存在一个函数或变量,其名称与类类型的名称相同,则可以在类之前添加类以消除歧义,从而生成elaborated type specifier

e.g。

int UInputComponent;
class UInputComponent { /* ... */ };

// without the class keyword it won't compile because the name UInputComponent is ambiguous
void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent) 

第3。第三种可能性,它可能没有任何意义。

如果已将UInputComponent声明为类,则使用关键字class或不使用关键字不会更改任何内容。请注意,如果先前声明的类型不匹配,则编译将失败。

答案 1 :(得分:1)

通常,class关键字用于声明新的类类型。但不是在这种情况下。

这称为前瞻声明 当您想要使用的类型未知时,将使用这些。 F.E.想象一下两个头文件。他们每个人都使用另一个人的类型。这是循环依赖,不允许。但是你仍然需要在每个文件中使用其他类型,对吗?

你可以做的是在一个文件中转发声明类型,然后你可以摆脱包含。摆脱包含解决了循环依赖关系并使你松散了所有类型的信息(可用成员f.e.),但你可以使用类型本身。这也为您节省了很多空间&#34;因为编译器不必包含其他标题。

我不想说太多,因为SO已经有了很好的答案:
When can I use a forward declaration?

该帖子没有涵盖的内容是您希望做出前瞻性声明的原因。正如我所说,它解决了循环依赖关系并使您免于包含类型。包含文件意味着让编译器将文件的内容复制到包含的位置。但是,您并不总是需要知道文件的内容。如果您只使用我链接的帖子中描述的功能,您可以保存包含。这反过来会减小编译器输出的大小。

答案 2 :(得分:1)

Unreal的工作原理

如您所知,Unreal管理相同基础类的多个实现以定义共同点。然后,每个开发人员必须从引擎必须提供的子类创建子类,以便在引擎内执行任务。

在这种情况下,它涉及 InputComponent ,它用于处理用户输入,解释它并将其传递给控制器和/或,随后,Pawns。

例如,如果要定义 Pawns PlayerControllers AIControllers 等元素, HUD 等等,您可以在 GameMode 中进行操作,然后通过 World Settings 直接配置到项目设置中(如果您的关卡需要特定的话) 游戏模式)。这些引用也是类,它们将在适当的时候由引擎实例化以设置游戏

陷入困境

考虑到这一点,这就是缺点。在UE4 C ++中(是的,它是一个东西!),由于引擎绑定了松散的末端,有时你不能使用某些类,因为它们没有被声明。当然,您可以包含它们但是要考虑一下:如果您为一个类创建所需的所有包含而只是为了找到另一个类可能间接需要那个包含它们,那么将创建多少个循环依赖项?

解决方案是前瞻声明。然而,这种情况是一种称为速记前瞻声明的特殊风格,您可以在其中使用类的确切位置声明类型

如果您只使用一次,这非常方便,因此您不会在文件开头处找到可怕的声明列表。

将此带到现实世界

例如,如果您想知道当前定义的默认Pawn类,您可以检查 GameMode 中的GetDefaultPawnClass公共变量(让我们称之为{{1} }})。变量定义如下:

MyGameMode

看到TSubclassOf < APawn > DefaultPawnClass ?这实际上是一个类模板,以确保类型安全。它实际上是对编辑的一个提示,只显示来自TSubclassOf的类。

如果您使用的是自定义类型并且基于我目前所讨论的内容,您可以找到以下内容:

APawn