簡體   English   中英

如何在 c++ 中的對象之間共享公共資源

[英]how to share common resource amongst objects in c++

在C++中,我經常遇到這個問題,總是一頭霧水。 假設有多個級別的類。 每個級別都在實例化 class,這是下一個級別。 例如,低於 level1 實例化 level2_a 和 b(在實際情況下還有更多)。 現在葉級 object 需要執行一些操作。 簡單的例子,假設葉級 object 需要將一些信息轉儲到狀態控制台。 所有葉級對象都需要這樣做。 在對象之間共享這個“狀態控制台”指針的最佳方式是什么(這些對象可能有 100 個)?

  1. 他們都需要存儲指向它的指針嗎?
  2. 或者將“狀態控制台”指針傳遞給某個成員 function 調用,然后它可以用來轉儲日志。

另一個這樣的例子,他們都需要共享一個堆棧,當它們被銷毀時,它們會在上面傳遞一些信息? 如何在所有這些葉級對象之間共享堆棧指針

例子:

class level2_a
{
<properties here differ from level2_b>
public:
    ~level2_a()
    {
        // dump some info into a common stack here
    }
    void dump_change_to_value(int newval)
    {
       // need a console pointer here 
       // but can't be singleton because there's 1 per window
    }
};

class level2_b
{
<properties here differ from level2_a>
public:
    ~level2_b()
    {
        // dump some info into a common stack here
    }
    void dump_change_to_value(int newval)
    {
       // need a console pointer here 
       // but can't be singleton because there's 1 per window
    }
};
class level1
{
private:
    level2_a* ml2_a;
    level2_b* ml2_b;    
public:
    <func members..>
};


如何在 level2_a 和 b 之間完成堆棧/控制台的共享

通常,我通過通常為 singleton 的共同類在 class 基地設置記錄器。

我顯然總是定義一些基本的記錄器:

  • Null 記錄器(不打印任何東西),
  • 控制台記錄器(標准 output / 錯誤),
  • 文件記錄器(是否合並stdout / stderr )。

很明顯,實際上,它是相同的 class,但實例化了不同的文件句柄。 內部的 singleton 實例存儲在一個 map 中,其中關鍵部分是傳遞給getInstance方法的值的元組。 然后,一旦實例已知,每個使用它的 class 都會將其存儲在shared_ptr中。

默認是通過 static 屬性在基礎 class 中設置您的記錄器,當創建新的派生實例時,這些屬性將用作“默認記錄器”。 但是每個實例也可以設置自己的“私有”記錄器,用於調試目的...例如,您可以將“NullLogger”設置為基數 class,並將“FileLogger”設置為當前調試的派生 class。

而且,顯然,您程序的 rest 仍然可以使用“SysLogger”在集中位置繼續正常日志,如rsyslog或類似的東西。

所有這一切僅依賴於 static 個成員,這些成員擁有默認值、真正使用的普通屬性(在構造函數和/或記錄器的設置器中設置),以及明顯的虛擬方法。

請注意,“默認”表示“記錄器在實例化時連接”,因此更改默認記錄器不會傳播到所有子實例......除非您在訪問記錄器時不斷使用三元運算符(使用類似於(mThisLogger?mThisLogger:sDefLogger)->log(...)可以放在一個內聯的私有繼承函數中)。

好的部分是您不必在初始連接后關心記錄器,如果需要它甚至會自動傳播(只需要互斥鎖/信號來更改它而不會弄亂一切)。 但是您仍然可以更改特定實例的記錄器,以便您可以僅為該實例設置不同的詳細級別,或者將日志發送到更方便的目的地(如干凈的控制台、獨立文件...)而不更改代碼中的任何其他內容,如下所示:

#ifdef _DEBUG   // or a "if (isDebug())" if you have such a function...
  annoyingInstance->setLog(allLoggersNamespace::DebugLogger);
  annoyingInstance->setLogLevel(Logger::FullTrace);
#endif

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM