参数前的"class"是什么意思?
What does "class" mean before parameter?
Unreal Engine 生成以下函数:
void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
//stuff...
}
注意参数类型前的 "class" 说明符。这是什么意思?
1.第一种可能性,如果之前没有声明UInputComponent
,这可能是一个forward declarations。所以
void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
forward声明了一个名为UInputComponent
的class,参数InputComponent
的类型为UInputComponent*
.
Note that a new class name may also be introduced by an elaborated
type specifier which appears as part of another declaration, but only
if name lookup can't find a previously declared class with the same
name.
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
可以用来消歧。
If a function or a variable exists in scope with the name identical to the name of a class type, class can be prepended to the name for disambiguation, resulting in an elaborated type specifier
例如
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,则使用或不使用关键字 class
不会改变任何内容。请注意,如果先前声明的类型不匹配,则编译将失败。
通常 class 关键字用于声明新的 class 类型。但不是在这种情况下。
这称为前向声明。
当您要使用的类型未知时使用这些。 F.e。想象一下两个 header 文件。他们每个人都使用另一个的类型。这是循环依赖,是不允许的。但是你仍然需要在每个文件中使用其他类型,对吗?
你可以做的是在一个文件中转发声明类型,然后你可以去掉包含。摆脱 include 解决了循环依赖并使您丢失了类型的所有信息(可用成员 f.e.),但您可以使用类型本身。这也为您节省了很多 "space" 因为编译器不必包含其他 header.
我不想说太多,因为已经有很好的答案了:
When can I use a forward declaration?
post 没有很好地说明您为什么要进行前向声明。正如我所说,它解决了循环依赖并使您免于包含类型。 include一个文件就是让编译器把文件的内容复制到include所在的地方。但您并不总是需要知道文件的内容。如果您可以仅使用我链接的 post 中描述的功能,则可以保存包含。这反过来会减少编译器输出的大小。
虚幻引擎的工作原理
您可能知道,Unreal 管理着相同 base classes 的 多个实现 来定义共同点。然后,每个开发人员都必须从引擎必须提供的内容中创建子 classes,以便在引擎中执行任务。
在这种情况下,它是关于一个 InputComponent,用于处理用户输入、解释它并将其传递给 Controllers and/or,随后,典当。
例如,如果要定义 Pawns、PlayerControllers、AIControllers[=56= 等元素]、HUD 等,您可以在 GameMode 中进行设置,然后配置到项目设置中,或者直接通过世界设置(以防您的关卡需要特定的游戏模式)。这些引用也是 classes,它们将在适当的时候由引擎实例化以设置 Game.
陷阱来了
考虑到这一点,缺点就来了。在 UE4 C++ 中(是的,这是一回事!),由于引擎将未解决的问题联系在一起,有时您将无法使用某些 classes,因为它们未声明。当然,您可以包含它们,但想一想:如果您将一个 class 所需的所有包含都包含进来,却发现另一个可能间接需要那个,将创建多少循环依赖?
解决方案是前向声明。然而,这种情况是一种特殊的风格,称为 Shorthand 前向声明,您在其中声明一个类型 在您使用 [=73= 的确切位置].
如果您只使用它一次,这将非常方便,这样您就不会在文件开头得到一个糟糕的声明列表。
将其带入现实世界
例如,如果您想知道当前定义的默认 Pawn class,您可以检查 GameMode[=56] 中的 GetDefaultPawnClass
public 变量=](我们称之为 MyGameMode
)。变量定义如下:
TSubclassOf < APawn > DefaultPawnClass
看到 TSubclassOf
了吗?这实际上是一个确保类型安全的 Class 模板。这实际上是对编辑器的提示,只向您显示源自 APawn
.
的 classes
如果您使用自定义类型并基于我目前所讨论的内容,您可以找到如下内容:
TSubclassOf<class ASpeedyPawn> MySpeedyPawn;
Unreal Engine 生成以下函数:
void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
//stuff...
}
注意参数类型前的 "class" 说明符。这是什么意思?
1.第一种可能性,如果之前没有声明UInputComponent
,这可能是一个forward declarations。所以
void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
forward声明了一个名为UInputComponent
的class,参数InputComponent
的类型为UInputComponent*
.
Note that a new class name may also be introduced by an elaborated type specifier which appears as part of another declaration, but only if name lookup can't find a previously declared class with the same name.
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
可以用来消歧。
If a function or a variable exists in scope with the name identical to the name of a class type, class can be prepended to the name for disambiguation, resulting in an elaborated type specifier
例如
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,则使用或不使用关键字 class
不会改变任何内容。请注意,如果先前声明的类型不匹配,则编译将失败。
通常 class 关键字用于声明新的 class 类型。但不是在这种情况下。
这称为前向声明。
当您要使用的类型未知时使用这些。 F.e。想象一下两个 header 文件。他们每个人都使用另一个的类型。这是循环依赖,是不允许的。但是你仍然需要在每个文件中使用其他类型,对吗?
你可以做的是在一个文件中转发声明类型,然后你可以去掉包含。摆脱 include 解决了循环依赖并使您丢失了类型的所有信息(可用成员 f.e.),但您可以使用类型本身。这也为您节省了很多 "space" 因为编译器不必包含其他 header.
我不想说太多,因为已经有很好的答案了:
When can I use a forward declaration?
post 没有很好地说明您为什么要进行前向声明。正如我所说,它解决了循环依赖并使您免于包含类型。 include一个文件就是让编译器把文件的内容复制到include所在的地方。但您并不总是需要知道文件的内容。如果您可以仅使用我链接的 post 中描述的功能,则可以保存包含。这反过来会减少编译器输出的大小。
虚幻引擎的工作原理
您可能知道,Unreal 管理着相同 base classes 的 多个实现 来定义共同点。然后,每个开发人员都必须从引擎必须提供的内容中创建子 classes,以便在引擎中执行任务。
在这种情况下,它是关于一个 InputComponent,用于处理用户输入、解释它并将其传递给 Controllers and/or,随后,典当。
例如,如果要定义 Pawns、PlayerControllers、AIControllers[=56= 等元素]、HUD 等,您可以在 GameMode 中进行设置,然后配置到项目设置中,或者直接通过世界设置(以防您的关卡需要特定的游戏模式)。这些引用也是 classes,它们将在适当的时候由引擎实例化以设置 Game.
陷阱来了
考虑到这一点,缺点就来了。在 UE4 C++ 中(是的,这是一回事!),由于引擎将未解决的问题联系在一起,有时您将无法使用某些 classes,因为它们未声明。当然,您可以包含它们,但想一想:如果您将一个 class 所需的所有包含都包含进来,却发现另一个可能间接需要那个,将创建多少循环依赖?
解决方案是前向声明。然而,这种情况是一种特殊的风格,称为 Shorthand 前向声明,您在其中声明一个类型 在您使用 [=73= 的确切位置].
如果您只使用它一次,这将非常方便,这样您就不会在文件开头得到一个糟糕的声明列表。
将其带入现实世界
例如,如果您想知道当前定义的默认 Pawn class,您可以检查 GameMode[=56] 中的 GetDefaultPawnClass
public 变量=](我们称之为 MyGameMode
)。变量定义如下:
TSubclassOf < APawn > DefaultPawnClass
看到 TSubclassOf
了吗?这实际上是一个确保类型安全的 Class 模板。这实际上是对编辑器的提示,只向您显示源自 APawn
.
如果您使用自定义类型并基于我目前所讨论的内容,您可以找到如下内容:
TSubclassOf<class ASpeedyPawn> MySpeedyPawn;