[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();

函数指针(类、结构体)

类型别名(类、结构体)

代理

单播代理

多播代理

动态代理

动态多播代理

代理是怎么调用引用函数的

posted @ 2024-04-18 19:15  啊賢  阅读(11)  评论(0编辑  收藏  举报