What does β€œclass” mean before a parameter?

Unreal Engine generates the following function:

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

Pay attention to the class specifier before the parameter type. What does it mean?

+4
source share
3 answers

How Unreal works

As you know, Unreal manages several implementations of the same base classes to define a common framework. Then, each developer must create child classes from those that the engine can offer to perform tasks in the Engine.

In this case, it is about the InputComponent, which is used to process user input, interprets it and passes it along with the controllers and / or, subsequently, pawns.

For example, if you want to define elements such as Pawns, PlayerControllers, AIControllers, HUD, etc., you do it in GameMode, then you configure it in the project settings or, directly, to a level through World Settings (in case your level requires a specific GameMode). These links are also classes that Engine will create at the time of the installation of the game.

Here goes the error

Given this, here comes the flip side. In UE4 C ++ (yes, this is the thing!), Since the engine binds the free ends, sometimes you won’t be able to use certain classes because they are not declared. Of course, you can include them, but think about it: how many circular dependencies will be created if you make all the inclusions that you need for one class, only to find another can indirectly require one?

Solution Forward declaration . This case, however, is a special flavor called an abbreviated forward declaration in which you declare a type in the place where you use the class.

This is very convenient if you just use it once, so at the beginning of the file you will not get a terrible list of ads.

Bringing it to the real world

For example, if you want to know the current Pawn class by default, you can check the public variable GetDefaultPawnClass in your GameMode (let it be MyGameMode ). A variable is defined as follows:

 TSubclassOf < APawn > DefaultPawnClass 

See what TSubclassOf ? This is actually a class template for type safety. This is actually a hint of an editor to show you only classes derived from APawn .

If you use a custom type and build on what I have discussed so far, you can find things like this:

 TSubclassOf<class ASpeedyPawn> MySpeedyPawn; 
+1
source

1. The first opportunity , it can be forward declarations if UInputComponent not declared earlier. So

 void AFlyingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent) 

forward declares a class called UInputComponent , and the InputComponent parameter is of type UInputComponent* .

Please note that a new class name can also be entered. A specifier type can be developed that appears as part of another declaration, but only if a name search cannot 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. Second possibility , the class keyword can be used for values.

If a function or variable exists in the scope with a name identical to the class type name, the class can be added to the name for the value, resulting in a specified type specifier

eg.

 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. The third possibility , this may mean nothing.

If the UInputComponent declared as a class, then using the class keyword or nothing will change. Note that if the previously declared type does not match, compilation will fail.

+8
source

Typically, a class keyword is used to declare a new class type. But not in this scenario.

This is called Forward Declaration .
They are used when the type you want to use is unknown. FE Submit two header files. Each of them uses the type of the other. This is a cyclical dependency and is not allowed. But you still need to use different types in each file, right?

What you can do is forward the type declaration to a single file, then you can get rid of include. Getting rid of include resolves the circular dependency and frees all type information (fe members available), but you can use the type itself. It also saves you a lot of space because the compiler should not include another header.

I don't want to talk too much, because there is already a great answer on SO:
When can I use forward declaration?

What this article does not describe very well is why you would like to make a declaration ahead. As I said, it solves circular dependencies and saves you from including a type. Including a file means that the compiler copies the contents of the file to where it is. But you do not always need to know the contents of the file. If you can get away with just those functions that are described in the post I linked, you can save include. This, in turn, will reduce the size of the compiler output.

+1
source

Source: https://habr.com/ru/post/1261827/


All Articles