簡體   English   中英

通過繼承而不是組合來鎖定

[英]Locking via inheritance rather than composition

在我編寫或評論的大多數代碼中,鎖定是通過組合實現的,其中一個類擁有一個關鍵部分或互斥鎖:

class MyClass
{
    Mutex mMutex;
};

當可以通過多個線程訪問可變成員時,我們通過RAII獲取並釋放鎖,如下所示:

void MyClass::Method()
{
    Lock lock(mMutex);
    // ...
}

今天我回顧了一些代碼通過繼承實現鎖定的代碼,如下所示:

class MyClass : public Mutex
{
    // ...
};

鎖定由類鎖定“本身”執行:

void MyClass::Method()
{
    Lock lock(this);
    // ...
}

這種方法有什么優點或缺點嗎? 或者這只是一個風格問題?

這幾乎沒有意義。 MyClass是某種擴展Mutex的同步對象嗎? 如果沒有,那么繼承幾乎可以肯定是錯誤的選擇,因為它沒有任何意義使用MyClass一個Mutex (的關系MyClassMutex不是“是”的關系)。

這也很危險:

MyClass x;
Lock lock(x);
x.Method();   // uh oh.

私有繼承可能對此更有意義,因為私有繼承或多或少是實現組合的一種方式。 但是,除非需要從Mutex繼承(如果Mutex有受保護的成員需要訪問),我認為使其成為成員的更標准的組合方法可能會減少混淆(就像人們想知道為什么繼承是而不是使Mutex成為會員)。

公開繼承可能有意義的一種情況是,您希望客戶端能夠出於某種原因鎖定該對象,然后他們可以簡單地將MyClass視為Mutex 這可能不是一個很好的設計選擇,因為如果對象以意想不到的方式被鎖定,你會為死鎖提供更多機會。 如果Mutex保持私有(無論是通過繼承還是通過標准組合),則類可以更確切地確定鎖的使用方式。

如果引入此設計的人受.NET影響,任何對象都是“可鎖定的”,我不會感到驚訝。 請注意,在.NET中,它曾經常見於lock(this) ,但這個習慣用法已經不受歡迎了,現在認為讓一個特定的私有對象成員用於鎖定更為正確。

暫無
暫無

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

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