介紹 的中文意思是易變的,是C++的一個關鍵字。它的作用就是允許修改被const修飾的對象的成員變數。 常用場景 什麼情況下我們會使用到mutable? 一般我們會用 修飾get類的函數,明確函數內部不會修改任何成員變數,但是如果內部的成員變數需要多線程讀寫,我們必須加鎖保證多線程安全。毫無疑問,加 ...
介紹
mutable
的中文意思是易變的,是C++的一個關鍵字。它的作用就是允許修改被const修飾的對象的成員變數。
常用場景
什麼情況下我們會使用到mutable?
一般我們會用const
修飾get類的函數,明確函數內部不會修改任何成員變數,但是如果內部的成員變數需要多線程讀寫,我們必須加鎖保證多線程安全。毫無疑問,加鎖操作是要修改鎖對象的,此時就用到了mutable
。
#include <mutex>
class A
{
public:
int get() const
{
std::lock_guard<std::mutex> lk( m );
return value;
}
void set( int v )
{
value = v;
return;
}
private:
mutable std::mutex m; // 不加mutable,編譯就會報錯
int value;
};
int main()
{
A a;
return;
}
還有比如我們使用std::set:
保存對象,當我們修改對象中非key的值時也需要用到mutable
,不然就得重新構造對象,設置非key的值,再重新塞入set
中。
#include <set>
class A
{
public:
void set( int v ) const
{
value = v;
return;
}
bool operator<( const A& rhs ) const
{
return key < rhs.key;
}
private:
int key;
mutable int value; // 不加mutable,編譯就會報錯
};
int main()
{
std::set<A> s;
s.insert( A() );
s.begin()->set( 10 );
return 0;
}
std::set
的迭代器類型總是const_iterator
。這很好理解,因為對象的在std::set
中的位置是根據其key值確定的,如果允許修改,那麼std::set
結構就不對了,再加上編譯器無法確定函數內是否會修改key,所以通過其迭代器對象操作的函數必須是const
修飾的。同理,std::map
的first
也是如此。
結合以上兩種情況,我們總結一下就能得出mutable
可以用來修飾const對象中那些不會影響外部觀察的成員。