c++ - Vector 实现中的 char* 缓冲区
问题描述
我一直在浏览向量/通用内存管理的实现。我在 codereview 上发现了一个问题,但我不明白其中一个建议是如何工作的。
这是问题相关部分的片段(代码):
template <class T> class Vector { public: typedef T* Iterator; Vector(); Vector(unsigned int size); Vector(unsigned int size, const T & initial); Vector(const Vector<T>& v); ~Vector(); unsigned int capacity() const; unsigned int size() const; bool empty() const; Iterator begin(); Iterator end(); T& front(); T& back(); void push_back(const T& value); void pop_back(); void reserve(unsigned int capacity); void resize(unsigned int size); T & operator[](unsigned int index); Vector<T> & operator = (const Vector<T> &); void clear(); private: unsigned int _size; unsigned int _capacity; unsigned int Log; T* buffer; };
参考这个答案,为什么他建议使用char*
缓冲区而不是T*
缓冲区,更重要的是,它是如何工作的,它是什么意思?我知道 char 指针没有初始化,但我认为你只能使用T*
......泛型类型如何适合 char 指针?
答案的相关部分:
如果缓冲区是 T 类型,您将很难完成这项工作。每次扩展缓冲区时,缓冲区中的所有元素都将使用 T 构造函数进行初始化。对于 int 来说,这不是问题。但是如果 T 有一个非平凡的构造函数,那么你将付出沉重的代价来初始化可能永远不会使用的元素。
T* buffer;
实际上,缓冲区应该是没有构造函数的东西。
char* buffer;
解决方案
解释就在答案中,
如果缓冲区的类型为 ,您将很难完成这项工作
T
。每次扩展缓冲区时,缓冲区中的所有元素都将使用T
构造函数进行初始化。因为int
这不是问题。但是如果T
有一个非平凡的构造函数,那么你将付出沉重的代价来初始化可能永远不会使用的元素。
什么时候可以使用
char* buffer_;
所有未使用的元素都buffer_
将包含未初始化的数据,但这没关系。您无需为使用非平凡的构造函数初始化每个对象而付出代价,您在使用时必须付出代价
T* buffer_;
@FrançoisAndrieux 提出了另一个有效观点。如果T
不是默认可构造的,您将无法使用它new T[capacity]
来分配内存。
关于您的评论,char
可以使用一组对象来保存任何对象。您只需要分配适当数量的char
对象。您必须分配对象capacity
数量,而不是对象数量。T
capacity*sizeof(T)
char
推荐阅读
- c# - c#如何将int数组转换为字符串二进制数组
- ionic3 - 如何在 ionic 中嵌入 javascript 播放器?
- sql - 具有多个参数的 Eloquent 过滤
- algorithm - Bellman-Ford 算法的部分证明
- ant - 如何使用 ANT 运行 jmeter
- r - 如何在 R 中计算 ROC 下的 AUC(插入符号、随机森林、支持向量机)
- c++ - QOpenGLWidget 不在整个小部件中渲染
- c# - 问题:System.Net.WebException:底层连接已关闭:接收时发生意外错误。System.NullReferenceException
- python - 列表元素列表的组合
- r - 为什么在 `[[` 有效时,当作为 FUN 参数传递给 sapply/lapply 时,`$` 未能对列表元素进行子集化?