在我编写或审查的大多数代码中,锁定是通过组合实现的,其中一个类拥有一个临界区或互斥锁:
class MyClass
{
Mutex mMutex;
};
当可变成员可以通过多个线程访问时,我们通过 RAII 获取和释放锁,如下所示:
void MyClass::Method()
{
Lock lock(mMutex);
// ...
}
今天我查看了一些代码,其中代码通过继承实现锁定,如下所示:
class MyClass : public Mutex
{
// ...
};
锁定是由类锁定“本身”执行的:
void MyClass::Method()
{
Lock lock(this);
// ...
}
这种方法有什么优点或缺点吗?或者这只是一个风格问题?
最佳答案
私有(private)继承可能更有意义,因为私有(private)继承或多或少是实现组合的一种方式。但是,除非需要从 Mutex
继承(例如,如果 Mutex
具有需要访问的 protected 成员),我认为使其成为成员的更标准的组合方法可能会引起更少的混淆(就像人们想知道为什么继承是使用而不是使 Mutex
成为成员)。
公开继承可能有意义的一种情况是您希望客户端能够出于某种原因锁定该对象,然后他们可以简单地将 MyClass
视为 Mutex
。这可能不是一个很好的设计选择,因为如果对象以意想不到的方式被锁定,就会有更多的机会发生死锁。如果 Mutex
保持私有(private)(无论是通过继承还是通过标准组合),该类可以更确定锁的确切使用方式。
如果介绍这种设计的人受到 .NET 的影响,其中任何对象都是“可锁定的”,我不会感到惊讶。请注意,在 .NET 中,它曾经对 lock(this)
很常见,但这种习惯用法已经不受欢迎,现在认为使用特定的私有(private)对象成员来锁定更正确。
关于c++ - 通过继承而不是组合锁定,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4425039/