---
title: "Unreal C++"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/unreal-cpp/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/05-游戏图形与运行时/Unreal/Unreal C++.md"
content_hash: 3638f45527b128c73dbb14c298bf3d592907fcedceeb3a46d7cfb4af785c61dd
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# Unreal C++

﻿# Unreal C++

> 创建时间：2022/3/11 19:11

* 概念
  * Compiling
    *   * 我的Q&A
    * Class Naming Prefix
  * 关于宏定义
    * C++宏定义
      * 可变宏
      * 运算符：#，##
      * 宏定义 vs. typedef
      * 宏定义 vs. 函数
      * 其他技巧与细节
    * Unreal宏定义
      * UCALSS
      * MYPROJECT_API
      * Unreal宏编译
      * 宏定义的方式
      * 常用宏配置与Unreal Editor中的效果
  * Objects & GC
    * Update
    * Destroy
  * Memory Management & GC
    * Root Set
    * Non-UObject References
    * 智能指针
  * 常用类型
    * Numeric Types
    * Strings
      * FString
      * FText
      * FName
      * TCHAR
    * Containers
      * TArray - std::vector
      * TMap - std::map
      * TSet - std::set
      * Cumtom TSet/TMap
  * Ref

## 概念

Forward Declaration

![assets/Unreal-C++__Image.png](/media/653ee82d9a20040f65c2.png)

## Compiling

###

https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/DevelopmentSetup/CompilingProjects/

## 我的Q&A

### Class Naming Prefix

Actor - A

Object - U
Enums - E
Interface - I
Template - T
SWidget - S
F - else

## 关于宏定义

### C++宏定义

编译过程

![assets/Unreal-C++__Image_1.png](/media/e7042ab54bca7a9d32f9.png)

![assets/Unreal-C++__Image_2.png](/media/12999ec4dd2b7ba73eb2.png)

https://blog.csdn.net/yanggangclcsdn/article/details/49704089

每个#define行（即逻辑行）由三部分组成：

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

指令 - “#”表示这是一条预处理命令，“define”为宏命令
宏（macro） - 一般为缩略语，其名称（宏名）一般大写，而且不能有空格，遵循C变量命令规则
替换文本”-任意常数、表达式、字符串等

包括 有参宏 和 无参宏 两种

#### 可变宏

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

#### 运算符：#，##

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```
```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

"##" 运算符也可以用在替换文本中，而它的作用是起到粘合的作用，即将两个语言符号组合成一个语言符号，所以又称为“ **预处理器的粘合剂（Preprocessor Glue）** ”。

#### 宏定义 vs. typedef

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

宏定义只是简单的字符串代换，在预处理阶段完成。而typede不是简单的字符串代换，而是可以用来做类型说明符的重命名的，类型的别名可以具有类型定义说明的功能，在编译阶段完成的。

#### 宏定义 vs. 函数

所以在宏定义中：#define COUNT(M) M * M 中的形参不分配内存单元，所以不作类型定义。而函数 int count(int x)中形参是局部变量，会在栈区分配内存单元，所以要作类型定义，而且实参与形参之间是“值传递”。而宏只是符号代换，不存在值传递。

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

COUNT(++x) 被替换为 ++x * ++x，即为 7 * 8 = 56，而不是想要 7 * 7 = 49
不要在有参宏用使用到“++”、“–”等

#### 其他技巧与细节

换行：在结尾加反斜杠，可使多行连接

宏定义必须写在函数之外，其作用域是 #define 开始，到源程序结束。

如果重复定义宏，则不同的编译器采用不同的重定义策略。

### Unreal宏定义

#### UCALSS

The UCLASS macro gives the UObject a reference to a UCLASS that describes its Unreal-based type.
UE4有一个管理游戏对象的强大系统。UObject是这个系统中所有对象的基类。UCLASS宏用于标记这些UObject的派生类，目的是把它们告知UObject管理系统。UCLASS的宏参数可以更加具体地指定该类型的各种行为。

每个 UCLASS 保留一个称作“类默认对象（Class Default Object）”的对象，简称 CDO。

The UCLASS() macro is used to indicate that a C++ class will be part of Unreal's **Reflection system**. This is necessary for the C++ class to be recognized by the Unreal Engine editor.
Another advantage of using UCLASS() is that you can use **Unreal Engine's memory management system** in the C++ class.

> UCLASS宏只能修饰UObject的子类。

类型说明符（Class Specifiers）

![assets/Unreal-C++__Image_3.png](/media/b8c53f0d7fb15529aa52.png)

元数据说明符（Metadata Specifiers）

![assets/Unreal-C++__Image_4.png](/media/91801a0e2f3a0275b785.png)

#### MYPROJECT_API

Specifying MYPROJECT_API is necessary if MyProject wishes to expose the UMyObject class to other modules.

#### Unreal宏编译

The compilation of an Unreal C++ project happens in two phases.

  1. In the first phase, UnrealHeaderTool (UHT) reads the C++ headers files looking for Unreal macros and generates the necessary code that will replace the macros.
  2. In the second phase, the C++ compiler compiles the resulting code.

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

For this class, UnrealHeaderTool will generate code that will be placed in the TutoProjectCollectable.generated.h file and code that will replace the GENERATED_BODY() macro.

#### 宏定义的方式

C++代码中定义

Build.cs文件和Target.cs文件中

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

在UBT代码的文件夹（`\Engine\Source\Programs\UnrealBuildTool`）中搜索Definitions.Add就可以看到编译时添加的宏定义。

#### 常用宏配置与Unreal Editor中的效果

https://blog.csdn.net/qq_29523119/article/details/85255854

## Objects & GC

https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Objects/

内存分配与容器：https://www.cnblogs.com/kekec/p/12012537.html

### Update

### Destroy

## Memory Management & GC

**UE4 uses the reflection system to implement a garbage collection system.**

Your classes need to derive from **UObject** in order to be enabled for garbage collection.

An object will **not be garbage collected** as long as **there is a path of references from an object in the root set to the object** in question.

If no such path to the root set exists for an object, it is called **unreachable** and will be **collected (deleted)** the next time the garbage collector runs.

The engine runs the garbage collector at certain **intervals**.

> UStructs cannot be garbage collected.

### Root Set

UObject pointer stored
in a UPROPERTY
in a UE4 container

Actors:
GC druing a level's shutdown
Once spawned, you must manually call Destroy on them to remove them from the Level without ending the Level.

This is important since, as mentioned before, **actors that have had Destroy called on them are not removed until the garbage collector runs again**. You can check the **IsPendingKill** method to see if a UObject is awaiting its deletion.

RootSet操作与判断

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

### Non-UObject References

Normal C++ objects (not derived from UObject) can also have the ability to add a reference to an object and prevent garbage collection --- derive from **FGCObject** and override its **AddReferencedObjects** method

### 智能指针

## 常用类型

### Numeric Types

int8/uint8: 8-bit signed/unsigned integer

int16/uint16: 16-bit signed/unsigned integer

int32/uint32: 32-bit signed/unsigned integer

int64/uint64: 64-bit signed/unsigned integer

float (32-bit) and double (64-bit) types

### Strings

#### FString

FString is a mutable string, analogous to std::string.

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

#### FText

localized text ???

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```
```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

#### FName

Rather than storing the complete string many times across every object that references it, FName uses a smaller storage footprint index that maps to a given string.

  * save memory when that string is used across many objects
  * save CPU time when comparing them- UE4 can simply check their index values to see if they match

#### TCHAR

The TCHAR type is used as a way of storing characters independent of the character set being used

https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/StringHandling/CharacterEncoding/

### Containers

相关资料：v

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

#### TArray - std::vector

like std::vector, offers a lot more functionality

```xml
public class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }

```

#### TMap - std::map

has quick methods for finding, adding, and removing elements based on their key

#### TSet - std::set

AddUnique, Contains - **faster**

#### Cumtom TSet/TMap

you will need to provide a **hash function** that takes a const pointer or reference to your type and returns a uint32
This return value is known as the object's **hash code** , and should uniquely identify the object.

## Ref

https://blog.csdn.net/yanggangclcsdn/article/details/49704089
https://romeroblueprints.blogspot.com/2020/10/the-uclass-macro.html
https://www.geek-share.com/detail/2802042559.html
https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/IntroductionToCPP/
