我将首先回答您的最后一个问题:
首先会发生什么:复制底层结构或破坏储物柜?
TL;DR:复制构造发生在销毁所有局部变量之前。
这已在 stackoverflow 上被多次询问,请参见此处、此处和此处。
CWG 1885对 C++14 标准应用了更精确的措辞:
N4606 §6.6.3 [stmt.return]/3
调用结果的复制初始化在由 return 语句的操作数建立的完整表达式末尾处的临时变量的销毁之前排序,而后者又在局部变量的销毁之前排序(6.6)包含 return 语句的块。
我有一个 MyClass 的 QList。从列表中添加和删除项目很少见,并且由常见的列表互斥锁控制。MyClass 包含几个子结构和个人 QReadWriteLock
拥有两个要锁定的互斥锁会使您容易出现死锁。但是,您可以通过遵循以下两个准则之一来避免这种情况:
- 避免嵌套锁,一次只锁定一个互斥锁。确保在获取新锁之前释放当前持有的锁。
- 如果这对您来说不可能,您必须始终以固定顺序获取锁,并且此顺序在整个应用程序中应该是一致的(即,在锁定特定
MyClass
实例的读/写互斥锁之前,始终锁定保护整个列表的互斥锁当您需要同时锁定两个互斥锁时)。
和我在二传手做的一样。使用这样的储物柜是一种好习惯吗?
假设您QWriteLocker
在设置器中使用过,这应该没问题(从某种意义上说,它不会导致未定义的行为)。但是你必须注意你的界面真正在说什么。例如,当您mc
对 type的实例执行类似操作时MyClass
:
Substructure s = mc.getSub();
if(s == anotherSubstructure)
mc.doSomething();
当执行上述代码的线程与 进行比较s
时anotherSubstructure
,另一个线程可能会更改实际的substructure
inside mc
,而前一个线程看不到这种更改(因为它有自己的 副本substructure
)。
关键是,当你这样做时Substructure s = mc.getSub();
,你唯一知道的是它的子结构在某个时间点mc
等于,并且一旦你释放函数中的锁,这个值可能会改变。s
getSub
在我上面的例子中,doSomething()
不能假设mc
' 子结构的值仍然等于anotherSubstructure
。您可能需要将需要在其自己的函数中具有原子性的操作分组(通过适当的锁确保在上述情况下值不会改变)。