【UE4 设计模式】单例模式 Singleton Pattern

概述

描述

  • 保证一个类只有一个实例
  • 提供一个访问该实例的全局节点,可以视为一个全局变量
  • 仅在首次请求单例对象时对其进行初始化。

套路

  • 将默认构造函数设为私有, 防止其他对象使用单例类的 new运算符。
  • 新建一个静态构建方法作为构造函数。

使用场景

  • 资源Manager,如 SoundManager、ParticeManager 等
  • 线程池
  • 多线程的单例模式,线程锁与双重检测

优缺点

  • 优点
    • 提供了对唯一实例的受控访问;
    • 由于内存只存在一个对象,因此可节约资源
    • 单例模式可以允许可变的数目的实例,使用单利模式进行扩展,使用控制单利对象相似的方法获取指定个数的实例,及解决了单利对象,共享过多,而有损性能的问题;
  • 缺点
    • 由于单例模式不是抽象的,所以可扩展性比较差;
    • 单例职责过重,在一定程度上违背了单一职责。(耦合性高)

UE4中的单例

GameInstance

  • 继承 GameInstance 创建类
  • Project Settings->Project->Game Instance -> Game Instance Class 设置为自定义类

Subsystem

  • 包括五类:
    • UEngineSubsystem
    • UEditorSubsystem
    • UGameInstanceSubsystem
    • UWorldSubsystem
    • ULocalPlayerSubsystem

自定义 Singleton Class

继承 UObject 自定义

  • 代码

    UCLASS(BlueprintType,Blueprintable)
    class DESIGNPATTERNS_API USingletonObject : public UObject
    {
    	GENERATED_BODY()
    public:
    	UFUNCTION(BlueprintCallable)
    		static USingletonObject* GetSingletonObjectIns();
    
    	UFUNCTION(BlueprintCallable)
    		void SetValue(int32 NewValue);
    
    	UFUNCTION(BlueprintCallable)
    		int32 GetValue();
    
    private:
    	static USingletonObject* SingletonObject;
    
    	int32 IntValue;	
    };
    
    USingletonObject* USingletonObject::SingletonObject = nullptr;
    
    USingletonObject* USingletonObject::GetSingletonObjectIns()
    {
    	if (SingletonObject == nullptr)
    	{
    		SingletonObject = NewObject<USingletonObject>();
    	}
    	return SingletonObject;
    }
    
    void USingletonObject::SetValue(int32 NewValue)
    {
    	IntValue = NewValue;
    }
    
    int32 USingletonObject::GetValue()
    {
    	UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Value = %d"), IntValue);
    	return IntValue;
    }
    

Game Singleton Class 指定

  • 继承 UObject 创建单例类

  • Project Settings->Engine->General settings->Game Singleton Class 设置为自定义的单例类。会自动生成与销毁

  • 把它当成全局常量来用,不建议运行中修改其中的变量数据

    image

  • 单例类代码,修改

    USingletonObject* USingletonObject::GetSingletonObjectIns()
    {
    	if (SingletonObject == nullptr) // 也可以判断 GEngine
    	{
    		SingletonObject = Cast<USingletonObject>(GEngine->GameSingleton);
    	}
    	return SingletonObject;
    }
    
    

参考

posted @ 2021-06-03 16:15  砥才人  阅读(2799)  评论(0编辑  收藏  举报