【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;
    }
    
    

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM