如何扩展std库容器,以便在单个元素发生更改时得到通知
How to extend std library containers to get notified when individual elements are changed
我想扩展std库容器,以便在容器的任何状态发生更改时通知应用程序。例如,当一个新项目被添加到列表中时,我希望容器调用应用程序中具有特定信息的方法。我的要求是跟踪由于给定操作而更改的内存地址。例如,如果插入一个新元素导致修改列表内部的某个对象,我想知道该对象的起始地址以及对象的大小,这样我就可以大致知道内存的哪个区域发生了更改。
更新:看来我的问题不是那么清楚。我不想拦截获取值的调用。相反,我想要的是跟踪内存是如何因操作而改变的。例如,当一个新元素添加到二叉树中时,树中某个节点中的指针会更新为指向新添加的节点。当这种情况发生时,我想得到这个节点的地址以及node类的大小的通知,这样我就可以放心地说,start_address到start_address+sizeof(NodeType)范围内的内存addess已经更改。在自定义内存池+自定义分配器的帮助下,我可以使用这些信息进行增量状态转储。
我不喜欢您给出的将地址返回到列表中内部内存位置的示例。如果有不同的线程使用可能无效的迭代器,则锁定容器直到该任务完成。
另一个例子是,当容器分配更多存储时发出通知,这是可以的。这里有一个非常简单的例子。我只实现了push(),它在底层向量上调用push_back。你甚至不能访问你已经推送的数据,但这对你来说很容易添加。
template <class T>
class notifyvector {
std::vector<T> _vector;
size_t _capacity;
static const size_t initial_capacity = 20;
public:
notifyvector() : _capacity(initial_capacity) {
_vector.reserve(initial_capacity);
}
void push(T value){
_vector.push_back(value);
if (_capacity < _vector.capacity()){
// the vector has grown
_capacity = _vector.capacity();
do_notify(_capacity);
}
}
void do_notify(size_t newcap){
// all you
std::cout << "the vector has grown to " << newcap << std::endl;
}
};
练习的重点是演示一个包装器,该包装器在控制底层容器的所有输入和输出的类中提供您想要的通知类型。这允许它检测事件并发送您想要的任何通知。
您可能允许访问底层容器的const引用(只读),并在写访问中检测要通知的事件,写访问必须通过容器的函数。
开箱即用,标准容器并不像您所描述的那样提供通知。
作为一个例子;
template<
class T,
class Allocator = std::allocator<T>
> class vector;
容器本质上有两个扩展点——类型T
和分配器Allocator
。容器的内部,例如节点、内部指针、计数器等,不会公开用于自定义。
为了模仿您想要的钩子,您需要利用标准容器的这两个扩展点。如果它们被证明是不够的,那么您将需要构建自己的容器。
提供自定义分配器可以帮助获得对象(对于使用它们的容器,这包括内部节点对象)构造、销毁和分配、释放等的通知。给定示例用法,自定义分配器可能是所需的全部;这些操作通常对应于容器增长、对象创建和销毁等。分配器提供(在分配期间)和被提供(在构造和销毁期间),内存的地址被更改。
您也可以包装容器中正在使用的类型,以通知您其状态的更改,但这可能过于夸张,并且很难识别容器本身和容器客户端所做的更改。
此外,您可以包装容器以提供所需的钩子,然后将所需功能的其余部分存根到所需容器的私有成员(或基类)。您甚至可以将其模板化以支持多种容器类型。
- 为什么平均打印数组元素比打印单个对象慢C++?
- C++:带有大括号初始化列表的函数调用表达式 - 标准是否规定在单个元素列表的微不足道的情况下忽略大括号?
- 如何在 c++ 中将整个数组初始化为类构造函数中的单个元素
- 删除二叉搜索树 (C++) 中的单个元素
- Leetcode 540 上的运行时错误.排序数组中的单个元素
- 使用一个内存集数组和单个堆栈在 O(n) 中查找数组的下一个更大元素
- 尝试从列表中随机选取单个元素并将其显示为C++
- 如何计算单个元素在向量<float>中所有元素之和中的百分比
- 我如何处理数组的单个元素
- 删除两个相邻的元素并用矢量中的单个元素替换它们
- 是否可以在C STL中获得集合的单个元素
- 从2D数组C 中删除单个元素
- 连续单个元素的敏感变量
- 在动态数组C 中删除单个元素
- 在C++中,如何在没有新元素且不单独声明单个元素的情况下创建"std::initializer_list<base *>"?
- 如何在多维数组中搜索单个行,然后对某些行中的每个单个元素执行计算
- 为什么数组(字符串类型)的大小是 24 字节,带有单个空格元素
- 移动单个矢量元素上的语义
- 如何在单个向量中查找匹配的元素
- 在什么基础上,由单个元素组成的参数包的折叠表达式被转换为未加括号的表达式