{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/unreal-cpp/",
  "atlas": "https://www.pystone.net/?node=unreal-cpp#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/unreal-cpp.md",
  "context": "https://www.pystone.net/notes/unreal-cpp.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:unreal-cpp",
  "slug": "unreal-cpp",
  "title": "Unreal C++",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "Unreal C++",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "3638f45527b128c73dbb14c298bf3d592907fcedceeb3a46d7cfb4af785c61dd",
  "assets": [
    {
      "reference": "assets/Unreal-C++__Image.png",
      "url": "/media/653ee82d9a20040f65c2.png",
      "mediaType": "image/png",
      "contentHash": "653ee82d9a20040f65c20d500106a49b3d5aae320719b78dad461bfcf9937ba6",
      "byteLength": 34816,
      "width": 1057,
      "height": 558
    },
    {
      "reference": "assets/Unreal-C++__Image_1.png",
      "url": "/media/e7042ab54bca7a9d32f9.png",
      "mediaType": "image/png",
      "contentHash": "e7042ab54bca7a9d32f9e460a63d4720e4ae03b997b6305d271e1b724740f7ac",
      "byteLength": 19638,
      "width": 680,
      "height": 487
    },
    {
      "reference": "assets/Unreal-C++__Image_2.png",
      "url": "/media/12999ec4dd2b7ba73eb2.png",
      "mediaType": "image/png",
      "contentHash": "12999ec4dd2b7ba73eb29ab63a81fb237b59e8b6dde5c4f55ceb43c4506c227d",
      "byteLength": 34730,
      "width": 741,
      "height": 176
    },
    {
      "reference": "assets/Unreal-C++__Image_3.png",
      "url": "/media/b8c53f0d7fb15529aa52.png",
      "mediaType": "image/png",
      "contentHash": "b8c53f0d7fb15529aa52a4763ac4c567605cf28c886a427e52e1b664ad12db6f",
      "byteLength": 27357,
      "width": 811,
      "height": 391
    },
    {
      "reference": "assets/Unreal-C++__Image_4.png",
      "url": "/media/91801a0e2f3a0275b785.png",
      "mediaType": "image/png",
      "contentHash": "91801a0e2f3a0275b7851acb53c3465885282f630de94ec1a9a4e6b7a8794288",
      "byteLength": 7364,
      "width": 806,
      "height": 176
    }
  ],
  "headings": [
    {
      "depth": 1,
      "text": "Unreal C++",
      "anchor": "unreal-c",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#unreal-c"
    },
    {
      "depth": 2,
      "text": "概念",
      "anchor": "概念",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E6%A6%82%E5%BF%B5"
    },
    {
      "depth": 2,
      "text": "Compiling",
      "anchor": "compiling",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#compiling"
    },
    {
      "depth": 2,
      "text": "我的Q&A",
      "anchor": "我的qa",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E6%88%91%E7%9A%84qa"
    },
    {
      "depth": 3,
      "text": "Class Naming Prefix",
      "anchor": "class-naming-prefix",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#class-naming-prefix"
    },
    {
      "depth": 2,
      "text": "关于宏定义",
      "anchor": "关于宏定义",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%85%B3%E4%BA%8E%E5%AE%8F%E5%AE%9A%E4%B9%89"
    },
    {
      "depth": 3,
      "text": "C++宏定义",
      "anchor": "c宏定义",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#c%E5%AE%8F%E5%AE%9A%E4%B9%89"
    },
    {
      "depth": 4,
      "text": "可变宏",
      "anchor": "可变宏",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%8F%AF%E5%8F%98%E5%AE%8F"
    },
    {
      "depth": 4,
      "text": "运算符：#，",
      "anchor": "运算符",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E8%BF%90%E7%AE%97%E7%AC%A6"
    },
    {
      "depth": 4,
      "text": "宏定义 vs. typedef",
      "anchor": "宏定义-vs-typedef",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%AE%8F%E5%AE%9A%E4%B9%89-vs-typedef"
    },
    {
      "depth": 4,
      "text": "宏定义 vs. 函数",
      "anchor": "宏定义-vs-函数",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%AE%8F%E5%AE%9A%E4%B9%89-vs-%E5%87%BD%E6%95%B0"
    },
    {
      "depth": 4,
      "text": "其他技巧与细节",
      "anchor": "其他技巧与细节",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%85%B6%E4%BB%96%E6%8A%80%E5%B7%A7%E4%B8%8E%E7%BB%86%E8%8A%82"
    },
    {
      "depth": 3,
      "text": "Unreal宏定义",
      "anchor": "unreal宏定义",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#unreal%E5%AE%8F%E5%AE%9A%E4%B9%89"
    },
    {
      "depth": 4,
      "text": "UCALSS",
      "anchor": "ucalss",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#ucalss"
    },
    {
      "depth": 4,
      "text": "MYPROJECTAPI",
      "anchor": "myprojectapi",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#myprojectapi"
    },
    {
      "depth": 4,
      "text": "Unreal宏编译",
      "anchor": "unreal宏编译",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#unreal%E5%AE%8F%E7%BC%96%E8%AF%91"
    },
    {
      "depth": 4,
      "text": "宏定义的方式",
      "anchor": "宏定义的方式",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%AE%8F%E5%AE%9A%E4%B9%89%E7%9A%84%E6%96%B9%E5%BC%8F"
    },
    {
      "depth": 4,
      "text": "常用宏配置与Unreal Editor中的效果",
      "anchor": "常用宏配置与unreal-editor中的效果",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%B8%B8%E7%94%A8%E5%AE%8F%E9%85%8D%E7%BD%AE%E4%B8%8Eunreal-editor%E4%B8%AD%E7%9A%84%E6%95%88%E6%9E%9C"
    },
    {
      "depth": 2,
      "text": "Objects & GC",
      "anchor": "objects-gc",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#objects-gc"
    },
    {
      "depth": 3,
      "text": "Update",
      "anchor": "update",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#update"
    },
    {
      "depth": 3,
      "text": "Destroy",
      "anchor": "destroy",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#destroy"
    },
    {
      "depth": 2,
      "text": "Memory Management & GC",
      "anchor": "memory-management-gc",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#memory-management-gc"
    },
    {
      "depth": 3,
      "text": "Root Set",
      "anchor": "root-set",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#root-set"
    },
    {
      "depth": 3,
      "text": "Non-UObject References",
      "anchor": "non-uobject-references",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#non-uobject-references"
    },
    {
      "depth": 3,
      "text": "智能指针",
      "anchor": "智能指针",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88"
    },
    {
      "depth": 2,
      "text": "常用类型",
      "anchor": "常用类型",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#%E5%B8%B8%E7%94%A8%E7%B1%BB%E5%9E%8B"
    },
    {
      "depth": 3,
      "text": "Numeric Types",
      "anchor": "numeric-types",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#numeric-types"
    },
    {
      "depth": 3,
      "text": "Strings",
      "anchor": "strings",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#strings"
    },
    {
      "depth": 4,
      "text": "FString",
      "anchor": "fstring",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#fstring"
    },
    {
      "depth": 4,
      "text": "FText",
      "anchor": "ftext",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#ftext"
    },
    {
      "depth": 4,
      "text": "FName",
      "anchor": "fname",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#fname"
    },
    {
      "depth": 4,
      "text": "TCHAR",
      "anchor": "tchar",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#tchar"
    },
    {
      "depth": 3,
      "text": "Containers",
      "anchor": "containers",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#containers"
    },
    {
      "depth": 4,
      "text": "TArray - std::vector",
      "anchor": "tarray---stdvector",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#tarray---stdvector"
    },
    {
      "depth": 4,
      "text": "TMap - std::map",
      "anchor": "tmap---stdmap",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#tmap---stdmap"
    },
    {
      "depth": 4,
      "text": "TSet - std::set",
      "anchor": "tset---stdset",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#tset---stdset"
    },
    {
      "depth": 4,
      "text": "Cumtom TSet/TMap",
      "anchor": "cumtom-tsettmap",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#cumtom-tsettmap"
    },
    {
      "depth": 2,
      "text": "Ref",
      "anchor": "ref",
      "citation": "https://www.pystone.net/notes/unreal-cpp/#ref"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "Unreal中的“Unreal C++”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#unreal"
    }
  ],
  "contentMarkdown": "# Unreal C++\n\n﻿# Unreal C++\n\n> 创建时间：2022/3/11 19:11\n\n* 概念\n  * Compiling\n    *   * 我的Q&A\n    * Class Naming Prefix\n  * 关于宏定义\n    * C++宏定义\n      * 可变宏\n      * 运算符：#，##\n      * 宏定义 vs. typedef\n      * 宏定义 vs. 函数\n      * 其他技巧与细节\n    * Unreal宏定义\n      * UCALSS\n      * MYPROJECT_API\n      * Unreal宏编译\n      * 宏定义的方式\n      * 常用宏配置与Unreal Editor中的效果\n  * Objects & GC\n    * Update\n    * Destroy\n  * Memory Management & GC\n    * Root Set\n    * Non-UObject References\n    * 智能指针\n  * 常用类型\n    * Numeric Types\n    * Strings\n      * FString\n      * FText\n      * FName\n      * TCHAR\n    * Containers\n      * TArray - std::vector\n      * TMap - std::map\n      * TSet - std::set\n      * Cumtom TSet/TMap\n  * Ref\n\n## 概念\n\nForward Declaration\n\n![](assets/Unreal-C++__Image.png)\n\n## Compiling\n\n###\n\nhttps://docs.unrealengine.com/4.27/en-US/ProductionPipelines/DevelopmentSetup/CompilingProjects/\n\n## 我的Q&A\n\n### Class Naming Prefix\n\nActor - A\n\nObject - U\nEnums - E\nInterface - I\nTemplate - T\nSWidget - S\nF - else\n\n## 关于宏定义\n\n### C++宏定义\n\n编译过程\n\n![](assets/Unreal-C++__Image_1.png)\n\n![](assets/Unreal-C++__Image_2.png)\n\nhttps://blog.csdn.net/yanggangclcsdn/article/details/49704089\n\n每个#define行（即逻辑行）由三部分组成：\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n指令 - “#”表示这是一条预处理命令，“define”为宏命令\n宏（macro） - 一般为缩略语，其名称（宏名）一般大写，而且不能有空格，遵循C变量命令规则\n替换文本”-任意常数、表达式、字符串等\n\n包括 有参宏 和 无参宏 两种\n\n#### 可变宏\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n#### 运算符：#，##\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n\"##\" 运算符也可以用在替换文本中，而它的作用是起到粘合的作用，即将两个语言符号组合成一个语言符号，所以又称为“ **预处理器的粘合剂（Preprocessor Glue）** ”。\n\n#### 宏定义 vs. typedef\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n宏定义只是简单的字符串代换，在预处理阶段完成。而typede不是简单的字符串代换，而是可以用来做类型说明符的重命名的，类型的别名可以具有类型定义说明的功能，在编译阶段完成的。\n\n#### 宏定义 vs. 函数\n\n所以在宏定义中：#define COUNT(M) M * M 中的形参不分配内存单元，所以不作类型定义。而函数 int count(int x)中形参是局部变量，会在栈区分配内存单元，所以要作类型定义，而且实参与形参之间是“值传递”。而宏只是符号代换，不存在值传递。\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\nCOUNT(++x) 被替换为 ++x * ++x，即为 7 * 8 = 56，而不是想要 7 * 7 = 49\n不要在有参宏用使用到“++”、“–”等\n\n#### 其他技巧与细节\n\n换行：在结尾加反斜杠，可使多行连接\n\n宏定义必须写在函数之外，其作用域是 #define 开始，到源程序结束。\n\n如果重复定义宏，则不同的编译器采用不同的重定义策略。\n\n### Unreal宏定义\n\n#### UCALSS\n\nThe UCLASS macro gives the UObject a reference to a UCLASS that describes its Unreal-based type.\nUE4有一个管理游戏对象的强大系统。UObject是这个系统中所有对象的基类。UCLASS宏用于标记这些UObject的派生类，目的是把它们告知UObject管理系统。UCLASS的宏参数可以更加具体地指定该类型的各种行为。\n\n每个 UCLASS 保留一个称作“类默认对象（Class Default Object）”的对象，简称 CDO。\n\nThe 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.\nAnother advantage of using UCLASS() is that you can use **Unreal Engine's memory management system** in the C++ class.\n\n> UCLASS宏只能修饰UObject的子类。\n\n类型说明符（Class Specifiers）\n\n![](assets/Unreal-C++__Image_3.png)\n\n元数据说明符（Metadata Specifiers）\n\n![](assets/Unreal-C++__Image_4.png)\n\n#### MYPROJECT_API\n\nSpecifying MYPROJECT_API is necessary if MyProject wishes to expose the UMyObject class to other modules.\n\n#### Unreal宏编译\n\nThe compilation of an Unreal C++ project happens in two phases.\n\n  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.\n  2. In the second phase, the C++ compiler compiles the resulting code.\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\nFor 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.\n\n#### 宏定义的方式\n\nC++代码中定义\n\nBuild.cs文件和Target.cs文件中\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n在UBT代码的文件夹（`\\Engine\\Source\\Programs\\UnrealBuildTool`）中搜索Definitions.Add就可以看到编译时添加的宏定义。\n\n#### 常用宏配置与Unreal Editor中的效果\n\nhttps://blog.csdn.net/qq_29523119/article/details/85255854\n\n## Objects & GC\n\nhttps://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Objects/\n\n内存分配与容器：https://www.cnblogs.com/kekec/p/12012537.html\n\n### Update\n\n### Destroy\n\n## Memory Management & GC\n\n**UE4 uses the reflection system to implement a garbage collection system.**\n\nYour classes need to derive from **UObject** in order to be enabled for garbage collection.\n\nAn 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.\n\nIf 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.\n\nThe engine runs the garbage collector at certain **intervals**.\n\n> UStructs cannot be garbage collected.\n\n### Root Set\n\nUObject pointer stored\nin a UPROPERTY\nin a UE4 container\n\nActors:\nGC druing a level's shutdown\nOnce spawned, you must manually call Destroy on them to remove them from the Level without ending the Level.\n\nThis 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.\n\nRootSet操作与判断\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n### Non-UObject References\n\nNormal 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\n\n### 智能指针\n\n## 常用类型\n\n### Numeric Types\n\nint8/uint8: 8-bit signed/unsigned integer\n\nint16/uint16: 16-bit signed/unsigned integer\n\nint32/uint32: 32-bit signed/unsigned integer\n\nint64/uint64: 64-bit signed/unsigned integer\n\nfloat (32-bit) and double (64-bit) types\n\n### Strings\n\n#### FString\n\nFString is a mutable string, analogous to std::string.\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n#### FText\n\nlocalized text ???\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n#### FName\n\nRather 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.\n\n  * save memory when that string is used across many objects\n  * save CPU time when comparing them- UE4 can simply check their index values to see if they match\n\n#### TCHAR\n\nThe TCHAR type is used as a way of storing characters independent of the character set being used\n\nhttps://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/StringHandling/CharacterEncoding/\n\n### Containers\n\n相关资料：v\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n#### TArray - std::vector\n\nlike std::vector, offers a lot more functionality\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n#### TMap - std::map\n\nhas quick methods for finding, adding, and removing elements based on their key\n\n#### TSet - std::set\n\nAddUnique, Contains - **faster**\n\n#### Cumtom TSet/TMap\n\nyou will need to provide a **hash function** that takes a const pointer or reference to your type and returns a uint32\nThis return value is known as the object's **hash code** , and should uniquely identify the object.\n\n## Ref\n\nhttps://blog.csdn.net/yanggangclcsdn/article/details/49704089\nhttps://romeroblueprints.blogspot.com/2020/10/the-uclass-macro.html\nhttps://www.geek-share.com/detail/2802042559.html\nhttps://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/IntroductionToCPP/\n"
}
