[10] UE C++ 拓展知识
注意点
序列化 : 人看的代码转成机器代码这一行为
单播支持带有返回值 , 多播不支持
单播执行内存消耗最小的
在蓝图里面使用多播
多态 ;
父类类型的指针指向子类的对象 , 调用父类的函数 , 展现子类的形态
调用函数的时候函数有很多重载 , 不知道输入什么参数怎么办 : 会的就填 , 不会的就不填
SaveGame
//--USnakeSaveGame.h
UCLASS()
class SNAKE_API USnakeSaveGame : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY()
int32 GameScore;
UPROPERTY()
FString Name;
UPROPERTY()
TArray<int32> Numbers;
FString SlotName;
int32 UserIndex;
FString SlotName1;
int32 UserIndex1;
USnakeSaveGame();
// int32 A
};
//--SnakeSaveGame.cpp
USnakeSaveGame::USnakeSaveGame()
{
SlotName = TEXT("FirstSlot");
UserIndex = 0;
}
HUD中使用
void ASnakeHUD::SaveGameInfoToSlot()
{
if (USnakeSaveGame* SnakeSaveGameInstance = Cast<USnakeSaveGame>(
UGameplayStatics::CreateSaveGameObject(USnakeSaveGame::StaticClass())))
{
SnakeSaveGameInstance->GameScore = 10;
SnakeSaveGameInstance->Name = TEXT("小黑");
SnakeSaveGameInstance->Numbers.Add(34);
SnakeSaveGameInstance->Numbers.Add(21);
UGameplayStatics::SaveGameToSlot(SnakeSaveGameInstance, SnakeSaveGameInstance->SlotName,
SnakeSaveGameInstance->UserIndex);
}
}
void ASnakeHUD::GetGameInfoFromSlot()
{
if (USnakeSaveGame* SnakeSaveGameInstance = Cast<USnakeSaveGame>(
UGameplayStatics::LoadGameFromSlot(TEXT("FirstSlot"), 0)))
{
int32 Number = SnakeSaveGameInstance->GameScore;
FString Name = SnakeSaveGameInstance->Name;
TArray<int32> Numbers = SnakeSaveGameInstance->Numbers;
UE_LOG(LogTemp, Log, TEXT("Number=%d;Name=%s;Numbers=%d"), Number, *Name, Numbers[1]);
}
}
静态变量的使用
静态变量 : 局部作用域、成员作用域、最终都是在静态全局区 , 且在UE5程序没关闭前都存在
//--ASnakeGameState.h
class SNAKE_API ASnakeGameState : public AGameStateBase
{
GENERATED_BODY()
public:
static int32 GameScore;
void AddGameScore();
};
//--ASnakeGameState.cpp
int32 ASnakeGameState::GameScore = 0; //独有一份
void ASnakeGameState::AddGameScore()
{
GameScore++;
}
//--使用
void ASnakeHUD::SaveGameInfoToSlot()
{
// ASnakeGameState::GameScore++;
static int32 N = 0; //局部作用域提升到静态区 , 即使函数执行完也不会回收
N++;
if (USnakeSaveGame* SnakeSaveGameInstance = Cast<USnakeSaveGame>(
UGameplayStatics::CreateSaveGameObject(USnakeSaveGame::StaticClass())))
{
SnakeSaveGameInstance->GameScore = ASnakeGameState::GameScore; //静态代码区赋值
SnakeSaveGameInstance->GameScore = N;
SnakeSaveGameInstance->Name = TEXT("小黑");
SnakeSaveGameInstance->Numbers.Add(34);
SnakeSaveGameInstance->Numbers.Add(21);
UGameplayStatics::SaveGameToSlot(SnakeSaveGameInstance, SnakeSaveGameInstance->SlotName,
SnakeSaveGameInstance->UserIndex);
}
}
全局函数指针和匿名函数
//函数指针 全局函数指针(Lambda表达式 匿名函数) 成员函数指针
//void Function1(int);
void Test1()
{
void (*Ptr)(int) = nullptr;//创建一个变量Ptr,Ptr可以(指向)存储一个无返回值,参数为int 的全局函数的地址
//函数指针的最终使用目的是传递参数使用的
Ptr = Function1;
Function1(10);
Ptr(10);
/*
//万能指针(C语言的指针)*/
void*a = malloc(sizeof(int));//在自由存储区(堆区)申请了10字节的内存空间
free(a);
int* ptr1 = (int*)a;
int*ptr = new int(10);//申请了堆区4字节的内存空间,并在空间中初始化为10
delete ptr;
}
void Test2(int(*CallBack)(), int a) //Test2 1. 需要执行自己的逻辑, 2. 要执行形参中函数的逻辑(回调函数)
{
int number = a;
std::cout << "number = " << number << std::endl;
CallBack();
}
//匿名函数 Lambda表达式 (一般用于全局函数指针传参)
void Function2()
{
/* [] 捕获列表(捕获父作用域下的属性的方式)
[] 不捕获父作用域下的属性
*/
// ()
// ->
/*
{} 函数逻辑
*/
int number = 100, a = 200, b = 300;
//[]
//{
// number;//不捕获
//};
//[=]
//{
// number;//值捕获(值的拷贝,只能使用,不能复制)
// number=100;//不能赋值
//};
[&]
{
number;//引用捕获(此处的number是父作用域下的属性number的别名)
number = 300;//可以借助别名赋值 ,但是赋值结果不会影响到父作用域
};
std::cout << "number=" << number << "\n";
[=, &number] //
{
number;//引用捕获(此处的number是父作用域下的属性number的别名)
number = 300;//可以借助别名赋值 ,但是赋值结果不会影响到父作用域
//a;
//a = 100;
};
std::cout << "number=" << number << "\n";
}
//--
// //匿名函数 []捕获列表 () ->void
[](int a)->int
{
std::cout << "[](int a)->int" << std::endl;
return 10;
};
//不捕获父作用域下的属性 函数参数为a 函数返回值为int 的匿名函数Lambda表达式
Test2([]()->int {std::cout << "[]()->int" << std::endl; return 6662; }, 79);
Function2();