当前位置: 首页 > news >正文

【UE5 C++课程系列笔记】10——动态单播/多播的基本使用

目录

概念

申明动态委托

一、DECLARE_DYNAMIC_DELEGATE 

二、DECLARE_DYNAMIC_MULTICAST_DELEGATE

绑定动态委托

一、BindDynamic

二、AddDynamic

三、RemoveDynamic

执行动态委托

​一、Execute 

二、ExecuteIfBound 

三、IsBound

四、Broadcast

动态单播使用示例

一、两个输入参数无返回值 

二、一个输入参数一个返回值 

动态多播使用示例


上一篇:【UE5 C++课程系列笔记】09——多播委托的基本使用-CSDN博客

概念

        动态单播/多播委托基于虚幻的反射系统,可以在蓝图中进行绑定等操作,这使得它在蓝图与 C++ 交互方面非常有用。动态单播只绑定一个函数,而动态多播可以绑定多个函数,与非动态的单播/多播相比,动态单播/多播提供了蓝图可访问性,使其能在蓝图中进行添加绑定、移除绑定以及调用等操作。与动态单播不同的是动态多播委托通常没有返回值。这是因为动态多播委托的主要目的是实现事件广播机制,它会依次调用所有绑定的函数。

申明动态委托

一、DECLARE_DYNAMIC_DELEGATE 

        DECLARE_DYNAMIC_DELEGATE 是虚幻引擎中用于声明动态单播委托类型的宏。动态委托允许在运行时更灵活地绑定函数,并且支持蓝图(UE 的可视化脚本系统)与 C++ 之间的交互。与普通委托相比,动态委托提供了一种更动态的方式来处理事件响应和函数回调,这在构建复杂的游戏系统,尤其是需要在蓝图中方便地配置和处理事件的场景下非常有用。

无参数的动态委托声明:DECLARE_DYNAMIC_DELEGATE (FDelegateName)。

带一个参数的动态委托声明:DECLARE_DYNAMIC_DELEGATE_OneParam (FDelegateName, ParamType, ParamName)。其中 ParamType 是参数类型,ParamName 是参数名称,用于在蓝图等环境中更清晰地标识参数。例如,声明一个带有一个 int 类型参数的动态委托:DECLARE_DYNAMIC_DELEGATE_OneParam (FMyDynamicDelegate, int, MyIntParam)。

二、DECLARE_DYNAMIC_MULTICAST_DELEGATE

        DECLARE_DYNAMIC_MULTICAST_DELEGATE 用于声明动态多播委托类型的宏。动态多播委托同样支持蓝图和 C++ 的交互,并且可以绑定多个函数。当触发这个委托时,所有绑定的函数都会被依次调用,这对于实现事件广播机制,特别是在需要多个对象或函数对同一事件做出响应,且这些响应可能需要在蓝图中灵活配置的场景下非常有用。

无参数的动态多播委托声明:DECLARE_DYNAMIC_MULTICAST_DELEGATE (FDelegateName)。

带一个参数的动态多播委托声明:DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam (FDelegateName, ParamType, ParamName)。例如,声明一个带有一个 float 类型参数的动态多播委托:DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam (FMyDynamicMulticastDelegate, float, MyFloatParam)。

绑定动态委托

一、BindDynamic

   BindDynamic是虚幻引擎(UE)中用于将函数绑定到动态单播委托上的方法,主要用于动态委托。这种绑定方式支持蓝图(UE 的可视化脚本系统)和 C++ 之间的交互,使得在运行时可以灵活地设置委托所关联的函数,并且能够让蓝图方便地对委托事件进行响应。

语法一般为:DelegateInstance.BindDynamic(ObjectPtr, &FunctionPointer)。其中DelegateInstance是委托实例,ObjectPtr是指向包含函数的对象的指针(通常是UObject指针),&FunctionPointer是要绑定的函数的地址。

在如下示例代码中,当玩家与一个物体交互时,触发一个动态委托。

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyInteractable.generated.h"// 声明一个带有一个FString参数(表示交互物体名称)的动态委托
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnInteract, FString, InteractableName);UCLASS()
class MYGAME_API AMyInteractable : public AActor
{GENERATED_BODY()
public:// 定义动态委托实例FOnInteract OnInteract;void Interact(FString Name){// 触发动态委托(如果已经绑定函数)OnInteract.ExecuteIfBound(Name);}
};class UMyInteractUI : public UUserWidget
{
public:void BindToInteractable(AMyInteractable* Interactable){if (Interactable){// 将本对象的函数动态绑定到交互物体的委托上Interactable->OnInteract.BindDynamic(this, &UMyInteractUI::OnInteractHandler);}}UFUNCTION(BlueprintImplementableEvent)void OnInteractHandler(FString InteractableName){// 这个函数可以在蓝图中实现具体的UI更新逻辑,比如显示交互物体的名称UE_LOG(LogTemp, Warning, TEXT("Interacted with: %s"), *InteractableName);}
};

二、AddDynamic

  AddDynamic主要用于将函数绑定到动态多播委托上。它和BindDynamic类似,都是用于动态地将函数关联到委托,但AddDynamic更侧重于多播委托的操作,用于在已经存在的动态多播委托基础上添加新的函数绑定,使得多个函数可以订阅(绑定)到这个委托,当委托被触发(调用Broadcast)时,所有绑定的函数都会被依次调用。

语法为:DynamicMulticastDelegateInstance.AddDynamic(ObjectPtr, &FunctionPointer)。其中DynamicMulticastDelegateInstance是动态多播委托实例,ObjectPtr是指向包含函数的对象的指针(通常是UObject指针),&FunctionPointer是要添加绑定的函数的地址。

在如下示例代码中,当角色释放技能时,通过动态多播委托通知多个系统进行响应。

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyCharacter.generated.h"// 声明一个带有一个int参数(表示技能ID)的动态多播委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSkillCast, int, SkillID);UCLASS()
class MYGAME_API AMyCharacter : public AActor
{GENERATED_BODY()
public:// 定义动态多播委托实例,并使用UPROPERTY(BlueprintAssignable)使其可在蓝图中绑定UPROPERTY(BlueprintAssignable)FOnSkillCast OnSkillCast;void CastSkill(int SkillId){// 触发动态多播委托OnSkillCast.Broadcast(SkillId);}
};class USkillEffectUI : public UUserWidget
{
public:void BindToCharacter(AMyCharacter* Character){if (Character){// 将本对象的函数动态绑定到角色的技能释放委托上Character->OnSkillCast.AddDynamic(this, &USkillEffectUI::OnSkillCastHandler);}}UFUNCTION(BlueprintImplementableEvent)void OnSkillCastHandler(int SkillId){// 在这里可以在蓝图中实现显示技能特效等相关逻辑UE_LOG(LogTemp, Warning, TEXT("Skill %d cast. Displaying effect..."), SkillId);}
};

三、RemoveDynamic

  RemoveDynamic用于从动态委托中移除之前通过BindDynamicAddDynamic绑定的函数。这在对象生命周期结束或者不再需要某个函数对委托事件做出响应时非常重要,可以避免委托在触发时调用已不存在或不需要的函数,从而防止程序出现错误或意外行为。

语法为:DelegateInstance.RemoveDynamic(ObjectPtr, &FunctionPointer)。其中DelegateInstance是委托实例,ObjectPtr是指向包含函数的对象的指针(通常是UObject指针),&FunctionPointer是要移除绑定的函数的地址。

在如下示例代码中,当一个 UI 对象被销毁时,需要从任务进度更新委托中移除它绑定的函数

#include "CoreMinimal.h"
#include "UObject/ObjectPtr.h"
#include "MyQuestSystem.h"
#include "QuestUI.h"void UQuestUI::UnbindFromQuestSystem(AMyQuestSystem* QuestSystem)
{if (QuestSystem){// 从任务系统的进度更新委托中移除本对象绑定的函数QuestSystem->OnQuestProgressUpdate.RemoveDynamic(this, &UQuestUI::OnQuestProgressUpdateHandler);}
}

执行动态委托

一、Execute 

        对于动态委托,Execute用于触发委托所绑定的函数执行。与普通委托类似,它会直接调用绑定的函数。不过在动态委托的语境下,它主要用于触发单播动态委托(通过DECLARE_DYNAMIC_DELEGATE声明的委托),并且要求委托必须已经绑定了函数,否则会导致程序崩溃,因为它不会检查委托是否绑定函数就尝试调用。

        对于无参数的动态委托实例DynamicDelegateInstance,使用DynamicDelegateInstance.Execute()。如果动态委托带有参数,比如声明了一个带有一个int类型参数的动态委托FMyDynamicDelegate,并且已经绑定了函数,在执行时语法为DynamicDelegateInstance.Execute(ParamValue),其中ParamValue是符合委托参数要求的int类型的值。

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyInteractableObject.generated.h"// 声明一个带有一个FString参数(表示交互提示信息)的动态委托
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnInteract, FString, InteractionPrompt);UCLASS()
class MYGAME_API AMyInteractableObject : public AActor
{GENERATED_BODY()
public:// 定义动态委托实例FOnInteract OnInteract;void Interact(){FString Prompt = "Interact with this object";// 假设委托已经绑定了函数,直接执行委托OnInteract.Execute(Prompt);}
};class UMyInteractUI : public UUserWidget
{
public:void BindToInteractable(AMyInteractableObject* Interactable){if (Interactable){// 将本对象的函数动态绑定到交互物体的委托上Interactable->OnInteract.BindDynamic(this, &UMyInteractUI::OnInteractHandler);}}UFUNCTION(BlueprintImplementableEvent)void OnInteractHandler(FString InteractionPrompt){// 在蓝图中实现显示交互提示信息的逻辑UE_LOG(LogTemp, Warning, TEXT("Interaction prompt: %s"), *InteractionPrompt);}
};

二、ExecuteIfBound 

        ExecuteIfBound是一种更安全的执行动态委托的方式,主要用于执行单播动态委托。它会先检查动态委托是否已经绑定了函数,如果已绑定,则执行该函数;如果未绑定,则不执行任何操作,这样可以避免因空指针引用而导致的程序错误。这种方法在不确定委托是否已经绑定函数的情况下非常实用,能够增强程序的健壮性。

        与Execute类似,对于无参数的动态委托实例DynamicDelegateInstance,使用DynamicDelegateInstance.ExecuteIfBound()。如果动态委托带有参数,例如一个带有一个float类型参数的动态委托,语法为DynamicDelegateInstance.ExecuteIfBound(ParamValue),其中ParamValue是符合委托参数要求的float类型的值。

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MySkill.generated.h"// 声明一个带有一个int参数(表示升级后的技能等级)的动态委托
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnSkillLevelUp, int, NewLevel);UCLASS()
class MYGAME_API AMySkill : public AActor
{GENERATED_BODY()
public:FOnSkillLevelUp OnSkillLevelUp;void LevelUp(int NewLevel){// 检查委托是否绑定函数,如果绑定则执行,否则不做任何事OnSkillLevelUp.ExecuteIfBound(NewLevel);}
};

三、IsBound

   IsBound用于检查动态委托是否已经绑定了函数。它返回一个布尔值,true表示动态委托已经绑定了函数,false表示没有绑定函数。这个方法在需要根据委托的绑定状态来执行不同逻辑的场景中非常有用,比如在触发委托之前先检查是否有函数可供执行,或者在动态配置委托绑定关系后检查绑定是否成功等。

        对于动态委托实例DynamicDelegateInstance,语法为bool IsBound = DynamicDelegateInstance.IsBound();

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyEventSystem.generated.h"// 声明一个无参数的动态委托
DECLARE_DYNAMIC_DELEGATE(FOnGameEvent);UCLASS()
class MYGAME_API AMyEventSystem : public AActor
{GENERATED_BODY()
public:FOnGameEvent OnGameEvent;void TriggerEventIfBound(){if (OnGameEvent.IsBound()){// 如果委托已经绑定函数,则触发委托OnGameEvent.ExecuteIfBound();}else{UE_LOG(LogTemp, Warning, TEXT("Event not bound, no function to execute."));}}
};

四、Broadcast

        对于多播动态委托,应该使用Broadcast方法来触发委托。Broadcast会按照函数绑定的顺序依次调用所有绑定的函数,从而实现事件广播的功能,让多个对象或函数对同一个事件做出响应。

示例代码:

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyEventSystem.generated.h"// 声明一个带有一个int参数(表示事件相关的数值)的多播动态委托
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMultiEvent, int, EventValue);UCLASS()
class MYGAME_API AMyEventSystem : public AActor
{GENERATED_BODY()
public:FOnMultiEvent OnMultiEvent;void TriggerEventCorrect(int Value){// 正确的用法,使用Broadcast触发多播委托OnMultiEvent.Broadcast(Value);}
};

动态单播使用示例

一、两个输入参数无返回值 

        在如下代码中,定义了一个名为 ADynamicSingleDelegateActor 的类,用于处理动态单播委托相关的功能。类中提供了初始化委托、调用委托以及释放委托的函数,分别是InitDynamicTwoParamsDelegate、CallDynamicTwoParamsDelegate、ReleaseDynamicTwoParamsDelegate。

头文件:

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DynamicSingleDelegateActor.generated.h"DECLARE_DYNAMIC_DELEGATE_TwoParams(FDynamicDelegate, FString, InName, int32, InMoney);UCLASS()
class STUDY_API ADynamicSingleDelegateActor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesADynamicSingleDelegateActor();UFUNCTION(BlueprintCallable)void InitDynamicTwoParamsDelegate(FDynamicDelegate InDelegate);UFUNCTION(BlueprintCallable)void CallDynamicTwoParamsDelegate(FString InStr, int32 InMoney);UFUNCTION(BlueprintCallable)void ReleaseDynamicTwoParamsDelegate();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;protected:FDynamicDelegate DynamicTwoParamsDelegate;
};

源文件:

// Fill out your copyright notice in the Description page of Project Settings.#include "Delegate/DynamicSingleDelegateActor.h"// Sets default values
ADynamicSingleDelegateActor::ADynamicSingleDelegateActor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;}void ADynamicSingleDelegateActor::InitDynamicTwoParamsDelegate(FDynamicDelegate InDelegate)
{DynamicTwoParamsDelegate = InDelegate;
}void ADynamicSingleDelegateActor::CallDynamicTwoParamsDelegate(FString InStr, int32 InMoney)
{DynamicTwoParamsDelegate.ExecuteIfBound(InStr, InMoney);
}void ADynamicSingleDelegateActor::ReleaseDynamicTwoParamsDelegate()
{DynamicTwoParamsDelegate.Clear();
}// Called when the game starts or when spawned
void ADynamicSingleDelegateActor::BeginPlay()
{Super::BeginPlay();}// Called every frame
void ADynamicSingleDelegateActor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}

编译后,在UEEditor中先创建派生自DynamicSingleDelegateActor的蓝图类,这里命名为“BP_DynamicSingleDelegateActor”

将“BP_DynamicSingleDelegateActor”拖入视口

在关卡蓝图中,设置运行开始时执行InitDynamicTwoParamsDelegate来绑定一个委托事件,然后当按下1键时,执行委托事件。

执行效果如下,当按下1键时成功触发绑定的自定义事件

二、一个输入参数一个返回值 

        在如下代码中,初始化委托、调用委托以及释放委托的函数,分别是 InitDynamicTwoParamsOneRetDelegate、CallDynamicTwoParamsOneRetDelegate、ReleaseDynamicTwoParamsOneRetDelegate

头文件

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DynamicSingleDelegateActor.generated.h"DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(int32, FDynamicDelegateRetOne, FString, InName);UCLASS()
class STUDY_API ADynamicSingleDelegateActor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesADynamicSingleDelegateActor();UFUNCTION(BlueprintCallable)void InitDynamicTwoParamsOneRetDelegate(FDynamicDelegateRetOne InDelegate);UFUNCTION(BlueprintCallable)void CallDynamicTwoParamsOneRetDelegate(FString InStr);UFUNCTION(BlueprintCallable)void ReleaseDynamicTwoParamsOneRetDelegate();protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;protected:FDynamicDelegateRetOne DynamicOneParamsOneRetDelegate;
};

源文件

// Fill out your copyright notice in the Description page of Project Settings.#include "Delegate/DynamicSingleDelegateActor.h"// Sets default values
ADynamicSingleDelegateActor::ADynamicSingleDelegateActor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = false;
}void ADynamicSingleDelegateActor::InitDynamicTwoParamsOneRetDelegate(FDynamicDelegateRetOne InDelegate)
{DynamicOneParamsOneRetDelegate = InDelegate;
}void ADynamicSingleDelegateActor::CallDynamicTwoParamsOneRetDelegate(FString InStr)
{int32 returnVal = DynamicOneParamsOneRetDelegate.Execute(InStr);UE_LOG(LogTemp, Warning, TEXT("return Value: %d"), returnVal);
}void ADynamicSingleDelegateActor::ReleaseDynamicTwoParamsOneRetDelegate()
{DynamicOneParamsOneRetDelegate.Clear();
}// Called when the game starts or when spawned
void ADynamicSingleDelegateActor::BeginPlay()
{Super::BeginPlay();
}// Called every frame
void ADynamicSingleDelegateActor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);
}

 编译后,在UEEditor中先创建派生自DynamicSingleDelegateActor的蓝图类,这里命名为“BP_DynamicSingleDelegateActor”

打开“BP_DynamicSingleDelegateActor”,在事件开始后调用InitDynamicTwoParamsOneRetDelegate,由于委托有返回值,这里用“Create Event”节点

创建一个匹配函数,在匹配函数内只打印一下传入的参数,并固定返回100

将蓝图“BP_DynamicSingleDelegateActor”拖入视口

在关卡蓝图中,通过按键1调用函数CallDynamicTwoParamsOneRetDelegate,从而执行委托事件

执行效果如下,可以看到成功打印委托的输入输出参数。

动态多播使用示例

        在如下代码中,定义了一个名为 ADynamicMultiDelegateActor 的类,用于处理动态多播委托相关的功能。类中提供了初始化委托、调用委托的函数,分别是InitDynamicMultiThree、CallDynamicMultiThree。 动态多播委托 FDynamicMultiThree带有三个不同类型的参数,用于传递参数信息。

 头文件

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DynamicMultiDelegateActor.generated.h"DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FDynamicMultiThree, FString, InName, int32, InHealth, int32, InMana);UCLASS()
class STUDY_API ADynamicMultiDelegateActor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesADynamicMultiDelegateActor();void InitDynamicMultiThree(FDynamicMultiThree InDelegate);UFUNCTION(BlueprintCallable)void CallDynamicMultiThree(FString InName, int32 InHealth, int32 InMana);protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;UPROPERTY(BLUEprintAssignable)FDynamicMultiThree DynamicMultiThree;
};

源文件

// Fill out your copyright notice in the Description page of Project Settings.#include "DynamicMultiDelegateActor.h"// Sets default values
ADynamicMultiDelegateActor::ADynamicMultiDelegateActor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = false;
}void ADynamicMultiDelegateActor::InitDynamicMultiThree(FDynamicMultiThree InDelegate)
{DynamicMultiThree = InDelegate;
}void ADynamicMultiDelegateActor::CallDynamicMultiThree(FString InName, int32 InHealth, int32 InMana)
{DynamicMultiThree.Broadcast(InName, InHealth, InMana);
}// Called when the game starts or when spawned
void ADynamicMultiDelegateActor::BeginPlay()
{Super::BeginPlay();
}// Called every frame
void ADynamicMultiDelegateActor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);
}

创建派生自“DynamicMultiDelegateActor”的蓝图类“BP_DynamicMultiDelegateActor”

打开“BP_DynamicMultiDelegateActor”,在事件开始运行时绑定委托事件

在关卡蓝图中,再次绑定委托。通过按键1调用CallDynamicMultiThree函数,从而调用所有绑定到动态多播委托的函数。

可以看到执行效果如下,按一次按键打印了两次“Test”,表示两个绑定的委托事件都成功触发。

相关文章:

【UE5 C++课程系列笔记】10——动态单播/多播的基本使用

目录 概念 申明动态委托 一、DECLARE_DYNAMIC_DELEGATE 二、DECLARE_DYNAMIC_MULTICAST_DELEGATE 绑定动态委托 一、BindDynamic 二、AddDynamic 三、RemoveDynamic 执行动态委托 ​一、Execute 二、ExecuteIfBound 三、IsBound 四、Broadcast 动态单播使用示…...

点击展示大图预览

原文链接在table表格里能够实现,点击里面的图片实现大图预览的效果; 一、先安装viewer — 使用npm安装 npm install v-viewer --save二、在main.js中引入 import Viewer from v-viewer //点击图片大图预览 import viewerjs/dist/viewer.css Vue.use(…...

【C++】分书问题:深入解析、回溯法高级应用与理论拓展

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述💯思路与算法回溯法理论基础 💯代码实现与解析完整代码代码关键步骤解析 💯时间复杂度与空间复杂度分析💯理论拓展&…...

java开发入门学习五-流程控制

流程控制语句 if, if...else, if..else if..else 与前端相同 略 switch case 与前端不同的是case不能使用表达式,使用表达式会报错 class TestSwitch {public static void main(String[] args) {// switch 表达式只能是特定的数据类型…...

【FFmpeg 教程 一】截图

本章使用 ffmpeg 实现观影中经常会用到的功能,截图。 以下给出两种方式。 课程需具备的基础能力:Python 1. 使用 subprocess 调用 FFmpeg 命令 import subprocess def extract_frame(video_path, output_image_path, timestamp"00:00:05")&qu…...

北邮,成电计算机考研怎么选?

#总结结论: 基于当前提供的24考研复录数据,从报考性价比角度,建议25考研的同学优先选择北邮计算机学硕。主要原因是:相比成电,北邮计算机学硕的目标分数更低,录取率更高,而且北邮的地理位置优势明显。对于…...

深入了解京东API接口:如何高效获取商品详情与SKU信息

在当今数字化时代,电商平台的数据接口成为了连接商家与消费者的桥梁。京东作为国内领先的电商平台,其API接口为开发者提供了丰富的商品信息获取途径。本文将深入探讨如何使用京东API接口高效获取商品详情与SKU信息,并附上简短而实用的代码示例…...

C++常见内存泄漏案例分析以及解决方案

C 常见内存泄漏案例分析以及解决方案 1. 分配与释放不匹配 在动态内存管理中,使用new操作符分配的内存必须通过delete操作符显式释放。若未遵循这一规则,将导致内存泄漏。例如: int *p new int; p new int; // 错误:未释放先…...

[LeetCode-Python版]206. 反转链表(迭代+递归两种解法)

题目 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:head [1,2] 输出:[2,1] 示例 3&#xff1…...

70 mysql 中事务的隔离级别

前言 mysql 隔离级别有四种 未提交读, 已提交读, 可重复度, 序列化执行 然后不同的隔离级别存在不同的问题 未提交读存在 脏读, 不可重复度, 幻觉读 等问题 已提交读存在 不可重复度, 幻觉读 等问题 可重复读存在 幻觉读 等问题 序列化执行 没有以上问题 然后 我们这里…...

C语言二叉树

1.思维导图 树 二叉树 2.将链式队列重新实现一遍 linkqueue.c #include"linkqueue.h" linkqueuePtr create() {linkqueuePtr L(linkqueuePtr)malloc(sizeof(linkqueue));if(NULLL){printf("队列创建失败\n");return NULL;}L->head(nodePtr)malloc(si…...

智能工厂的设计软件 三种处理单元(NPU/GPU/CPU)及其在深度学习框架中的作用 之1

本文要点 深度学习:认知系统架构的处理层 在认知系统架构的设计和代码实现上 需要考虑多个层次,包括感知层、处理层、决策层和执行层。其中 深度学习主要用来解决处理层上的认知问题。 感知层:负责收集外部环境的信息。 处理层:…...

iOS swift开发系列--如何给swiftui内容视图添加背景图片显示

我需要在swiftui项目中显示背景图,有两种方式,一种是把图片拖入asset资源中,另外一种是直接把图片放在源码目录下。采用第一种方式,直接把图片拖到资源目录,但是swiftui项目没有弹出, “Copy items if need…...

jmeter后端监视器

一、概述 JMeter 后端监听器(Backend Listener)是 JMeter 提供的一个功能强大的插件,用于将测试执行期间收集的性能数据发送到外部系统进行监控和分析。通过后端监听器,您可以实时地将 JMeter 测试执行期间收集的数据发送到外部系统,如图形化展示、数据库、数据分析工具等…...

服务器数据恢复—RAIDZ离线硬盘数超过热备盘数导致阵列崩溃的数据恢复案例

服务器存储数据恢复环境: ZFS Storage 7320存储阵列中有32块硬盘。32块硬盘分为4组,每组8块硬盘,共组建了3组RAIDZ,每组raid都配置了热备盘。 服务器存储故障: 服务器存储运行过程中突然崩溃,排除人为误操…...

面试题整理4----lvs,nginx,haproxy区别和使用场景

LVS、Nginx、HAProxy:区别与使用场景 1. LVS(Linux Virtual Server)1.1 介绍1.2 特点1.3 使用场景 2. Nginx2.1 介绍2.2 特点2.3 使用场景 3. HAProxy3.1 介绍3.2 特点3.3 使用场景 4. 总结对比 在构建高可用、高性能的网络服务时&#xff0c…...

iOS - 超好用的隐私清单修复脚本(持续更新)

文章目录 前言开发环境项目地址下载安装隐私访问报告隐私清单模板最后 前言 在早些时候,提交应用到App Store审核,大家应该都收到过类似这样的邮件: Although submission for App Store review was successful, you may want to correct th…...

html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>

1.代码 <ul><li>电话&#xff1a;<a href"tel:18888888888">188-8888-8888</a></li><li>邮箱&#xff1a;<a href"mailto:10000qq.com">10000qq.com</a></li><li>邮箱&#xff1a;<a hre…...

clickhouse-副本和分片

1、副本 1.1、概述 集群是副本和分片的基础&#xff0c;它将ClickHouse的服务拓扑由单节点延伸到多个节点&#xff0c;但它并不像Hadoop生态的某些系统那样&#xff0c;要求所有节点组成一个单一的大集群。ClickHouse的集群配置非常灵活&#xff0c;用户既可以将所有节点组成…...

2009 ~ 2019 年 408【计算机网络】大题解析

2009 年 路由算法&#xff08;9’&#xff09; 讲解视频推荐&#xff1a;【BOK408真题讲解-2009年&#xff08;催更就退网版&#xff09;】 某网络拓扑如下图所示&#xff0c;路由器 R1 通过接口 E1 、E2 分别连接局域网 1 、局域网 2 &#xff0c;通过接口 L0 连接路由器 R2 &…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解

一、前言 在HarmonyOS 5的应用开发模型中&#xff0c;featureAbility是旧版FA模型&#xff08;Feature Ability&#xff09;的用法&#xff0c;Stage模型已采用全新的应用架构&#xff0c;推荐使用组件化的上下文获取方式&#xff0c;而非依赖featureAbility。 FA大概是API7之…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...