Over-using mutable to enhance security?
假设我有一个具有指针数组的类,我有一个方法取消引用指针并将其作为引用返回。 我想允许方法调用者调用指针指向的对象的非const方法,但也希望保护自己免受调用者更改指针所指向的内容。 如果我返回一个const引用,我必须将许多指针对象的方法标记为const,因此它的许多类成员变量都是可变的。
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include <iostream> #include #include <memory> class Counter { public: Counter(); void hit() const; void reset(); unsigned count() const; private: mutable unsigned count_; }; Counter::Counter() : count_(0) {} void Counter::hit() const { ++count_; } void Counter::reset() { count_ = 0; } unsigned Counter::count() const { return count_; } class CircularArray { public: CircularArray(); const Counter& next() const; private: mutable unsigned i_; std::array<std::unique_ptr<Counter>, 3> arr_; }; CircularArray::CircularArray() : i_(2) { arr_[0] = std::unique_ptr<Counter>(new Counter); arr_[1] = std::unique_ptr<Counter>(new Counter); arr_[2] = std::unique_ptr<Counter>(new Counter); } const Counter& CircularArray::next() const { return *arr_[(i_ = (i_ + 1) % 3)]; } int main() { CircularArray circular; const Counter* p; p = &circular.next(); p->hit(); p->hit(); Counter c; //*p = c; // <-- Want to prevent this } |
为了扩展我所说的内容,滥用
1 | *p = /* ... */; |
然后通过删除
1 2 3 4 5 | class Counter { void operator=(const Counter&) = delete; // ... }; |
请记住,赋值运算符不会影响对象的标识:它不会更改其地址。 语义上,涉及修改
1 2 3 4 | // a very inefficient way of performing `*p = c` p->reset(); while (p->count() != c.count()) p->hit(); |
这实现了与执行分配完全相同的结果,尽管非常笨拙且效率低下。
执行赋值与调用接受类型