複数のスレッドから参照されるクラスのメンバに
CCriticalSection m_cs;
を用意し、メンバ変数にアクセスする箇所で排他制御をしようとしました。
ところが、実際にメンバ変数にアクセスするだけのメンバ関数を
void CHoge::SetValue(LPCTSTR pStrValue1, LPCTSTR pStrValue2)
{
CSingleLock lock(&m_cs, TRUE);
m_strValue1 = pStrValue1;
m_strValue2 = pStrValue2;
}
void CHoge::GetValue(CString* pStrValue1, CString* pStrValue2) const
{
CSingleLock lock(&m_cs, TRUE);
*pStrValue1 = m_strValue1;
*pStrValue2 = m_strValue2;
}
などとやってみたところ(上記の関数は極端な例です)、
CHoge::GetValue()のほうではm_csがconstになってしまい、
「const CCriticalSection *' から 'CSyncObject *' に変換できません」
と言われてしまいます。
それ自体の意味はもちろんわかっていますが、
メンバ変数の値を教えるだけのメンバ関数なのに
constを付けられないのにはちょっと違和感を感じます。
1. メンバ関数をconstにするのを諦める
2. m_csをCCriticalSectionではなくCCriticalSection*にしてnewで作成
3. m_csをmutableにする
という3つの方法を考えたのですが、
MFCでメンバに同期オブジェクトを持たせて排他制御する場合、
どのようにするのが一般的なのでしょうか?
俺なら 3. そもそも mutable の導入根拠がこういう事例なので。
# もし mutable がなければ 2. かな。
# そういう意味で mutable は無くても困らない程度のもので...
クラスを使う者から見ると、メンバ関数の挙動は const に見える
クラスを実装する者としては、実装上の都合で non-const なメンバが必要
という場合に mutable を使うのは自然な動きだと思う。
> 俺なら 3. そもそも mutable の導入根拠がこういう事例なので。
いままでmutableを自分のプログラムに組み込んだことがなかったのですが、
このようなときに使うべきものだったのですね。
無事にconstメンバ関数のまま排他制御することができました。
ありがとうございます。