以允许响应更新的方式重载 C++ 索引下标运算符 []
考虑编写一个可索引类的任务,该类自动将其状态与某些外部数据存储(例如文件)同步.为了做到这一点,类需要知道可能发生的对索引值的更改.不幸的是,重载 operator[] 的常用方法不允许这样做,例如...
Consider the task of writing an indexable class which automatically synchronizes its state with some external data-store (e.g. a file). In order to do this the class would need to be made aware of changes to the indexed value which might occur. Unfortunately the usual approach to overloading operator[] does not allow for this, for example...
Type& operator[](int index)
{
assert(index >=0 && index < size);
return state[index];
}
有什么方法可以区分正在访问的值和正在修改的值吗?
I there any way to distinguish between a value being accessed and a value being modified?
Type a = myIndexable[2]; //Access
myIndexable[3] = a; //Modification
这两种情况都发生在函数返回之后.是否有其他一些方法来重载 operator[] 可能更有意义?
Both of these cases occur after the function has returned. Is there some other approach to overloading operator[] which would perhaps make more sense?
推荐答案
从操作员[]你只能真正告诉访问.
即使外部实体使用非成本版本,这也并不意味着写入将发生,而是可能发生.
From the operator[] you can only really tell access.
Even if the external entity uses the non cost version this does not mean that a write will take place rather that it could take place.
因此,您需要做的是返回一个可以检测修改的对象.
最好的方法是用一个覆盖operator=
的类包装对象.当对象被更新时,这个包装器然后可以通知商店.您还需要覆盖 operator Type
(强制转换),以便可以检索对象的 const 版本以进行读取访问.
As such What you need to do is return an object that can detect modification.
The best way to do this is to wrap the object with a class that overrides the operator=
. This wrapper can then inform the store when the object has been updated. You would also want to override the operator Type
(cast) so that a const version of the object can be retrieved for read accesses.
然后我们可以这样做:
class WriteCheck;
class Store
{
public:
Type const& operator[](int index) const
{
return state[index];
}
WriteCheck operator[](int index);
void stateUpdate(int index)
{
// Called when a particular index has been updated.
}
// Stuff
};
class WriteCheck
{
Store& store;
Type& object;
int index;
public: WriteCheck(Store& s, Type& o, int i): store(s), object(o), index(i) {}
// When assignment is done assign
// Then inform the store.
WriteCheck& operator=(Type const& rhs)
{
object = rhs;
store.stateUpdate(index);
}
// Still allow the base object to be read
// From within this wrapper.
operator Type const&()
{
return object;
}
};
WriteCheck Store::operator[](int index)
{
return WriteCheck(*this, state[index], index);
}
一个更简单的选择是:
您没有提供 operator[],而是在 store 对象上提供特定的 set 方法,并且仅通过 operator[]
An simpler alternative is:
Rather than provide the operator[] you provide a specific set method on the store object and only provide read access through the operator[]
相关文章