什么时候可以,什么时候不能调用可变变量?
用int/float/bool值就很清楚了。
但是,比方说,数组呢?如果我要向它添加元素,我可以调用原生数组 mutable
吗?与 std::vector
相同。
再举一个例子。我有对象 A,它保持对另一个对象 B 的引用(B 和 b)。对象 B 有我将重新分配的 native 数组/std::vector(我认为在这种特殊情况下是相似的)。伪代码:
struct B{
std::vector<int> arr;
// int *arr; //Or this
void changeArr(){
arr.push_back(90);
}
}
struct A{
A(B &b) : b(b){};
mutable B &b; // is it ok to have it "mutable"?
//mutable B b; // or even this?
void fire() const{
b.arr.push_back(125);
// Or
b.changeArr();
}
}
我可以调用 B &b
可变吗?
更新
根据 http://en.cppreference.com/w/cpp/language/cv :
mutable - defines that a member of a class does not affect the externally visible state of the class.
这个类的外部可见状态
是什么?当我增加数组大小时,我是否会更改它,重新分配一些东西?如果没有,什么时候会改变?
最佳答案
让我们举两个经典的例子来说明可变的地方有帮助:
1。记住计算 ( memoization )
class prime_caclulator {
private:
mutable std::vector<int> m_primes;
public:
get(int n) const {
// 1. If the nth prime is in m_primes, return it.
// 2. Otherwise, calculate the nth prime.
// 3. Store the nth prime in m_primes.
// 4. Return that prime.
}
};
这里,我们有一个 const 函数 get()
,它不需要改变这个对象的内部状态来计算第 n 个素数。但是,跟踪以前计算的素数可能有助于提高该对象的性能。
这个内部状态,在这里我们称之为 m_primes
,当调用 get()
时可能会改变,因此我们需要将其标记为可变的。请注意,该对象的不同内容只会改变此调用所花费的时间,而不会改变它最终返回的内容。
2。线程安全
template <typename T>
class thread_safe_queue {
private:
mutable std::mutex m_mutex;
std::queue<T> m_queue;
public:
size_t size() const {
std::lock_guard<std::mutex> lock(m_mutex);
return m_queue.size();
}
void push(T value) {
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push(value);
}
T pop() {
std::lock_guard<std::mutex> lock(m_mutex);
T top = m_queue.front();
m_queue.pop();
return top;
}
};
在这种情况下,如果我们没有可变互斥体,那么我们将无法使 size()
成为常量,因为我们修改了 m_mutex
该函数的过程。
关于C++ 可变说明符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24267930/