实施C 模板列表类的有效初始化
Implementing efficient initialization of C++ Template List classes
用于编写模板列表类,相当于向量(纯粹是设计练习(,我正在尝试找出要高效的事情。
如果写信:
v = new T[size];
然后,编译器将调用T
的构造函数,对吗?T()
。
因此,在下面的课程中:
v = (T*) new char[sizeof(T) * size]
这似乎很容易。但是,在破坏者中,如何仅删除被初始化的删除?在下一类中,只有第一个"使用"元素被初始化。
另外,在复制构造函数中,如何仅对使用的元素调用T
的复制构造函数?
如果我初始化了昂贵的方式,则可以使用:
v = new T[size];
for (int i = 0; i < used; i++)
v[i] = orig.v[i];
,但这要求v
已经通过T()
进行直观化。更好的方法是什么?
类如下:
#include <cstdint>
template<typename T>
class List {
private:
uint32_t used;
uint32_t capacity;
T* v;
public:
List(uint32_t cap) : used(0), capacity(cap), v((T*)new char[sizeof(T)*capacity]) {}
~List() {
delete [] v; // no
}
List(const List& orig) : used(orig.used), capacity(orig.capacity), v((T*) new char[sizeof(T)*capacity]) {
// now copy only the used ones
for (int i = 0; i < used; i++)
v[i] = orig.v[i]; // no, operator = will call destructor on v[i], but it is uninitialized
}
};
要像 std::vector
一样,您需要使用"放置新"并明确调用破坏者。
#include <new>
~List() {
while (used) {
--used;
v[used]->~T();
}
delete[] reinterpret_cast<char*>(v);
}
List(const List& orig) : used(orig.used), capacity(orig.capacity),
v(reinterpret_cast<T*>(new char[sizeof(T)*capacity])) {
// now copy only the used ones
for (int i = 0; i < used; i++)
new(v+i) T(orig.v[i]);
}
注意以上复制构造函数并不是例外安全。尝试这样做。
首先,只需使用 std::vector<T>
而不是自己重新实现。
您在这里寻找的是放置新和显式驱动器调用。通常,每个new
都应与delete
配对,每个位置都应与明确的destructor调用配对。
回答您的特定问题:
然而,在灾难中,如何仅删除已被初始化的删除?
明确调用其破坏者,然后 char[]
正确分配了原始CC_11,它将(正确(自动调用任何T
destructors。
for (uint32_t i = 0; i < used; ++i) {
v[i]->~T();
}
delete [] reinterpret_cast<char *>(v);
另外,在复制构造函数中,如何有效地调用
T
的复制构造函数?
您需要在这里安置。您的行v[i] = orig.v[i];
会导致不确定的行为,因为尚未构建v[i]
。
放置对象而改用对象(使用该对象在使用之前应对每个 v[i]
进行操作(:
new(reinterpret_cast<char *>(v + i)) T(orig.v[i]);
对于复制构造函数,您可以尝试此代码:
#include <cstring>
List(const List& orig) : used(orig.used), capacity(orig.capacity), v((T*) new char[sizeof(T) * capacity]) {
// now copy only the used ones
memcpy(v, orig.v, sizeof(T)*capacity);
}
或
List(const List& orig) : used(orig.used), capacity(orig.capacity), v((T*) new char[sizeof(T) * capacity]) {
// now copy only the used ones
memcpy_s(v, capacity, orig.v, sizeof(T)*capacity);
}
相关文章:
- 为什么这种直接初始化有效?(C++17)
- 在C++中初始化向量映射的最有效方法
- 有效地初始化 const std::vector 类成员
- 有没有办法自动初始化 std::shared_ptr 来保存有效对象?
- 让构造函数在其初始化列表中调用同一类的另一个构造函数是否有效
- 如何有效地初始化大型类的对象
- 实施C 模板列表类的有效初始化
- static_assert未初始化的具有有效专用化的模板类中
- 为什么即使尚未初始化,获取字符串[0]也是有效的?
- 如何在函数中初始化矩阵并在C++中有效地返回它
- 具有从特定范围的随机数初始化特征矩阵或向量初始化特征矩阵或向量的有效方法
- 使用大型数据集初始化类成员向量的最有效方法
- 添加和初始化新std::map元素的最有效方法是什么
- 使用类型推断声明变量是否与"classical way"变量名称后用括号初始化变量一样有效?
- 在外部功能中具有一个变量初始化或内部功能中的多个初始化是最有效的
- 空字符数组的初始化是否有效
- WaitCommEvent 在启动时不会返回(当通过 MatLAB 初始化 COMPort 时有效)
- 具有未初始化成员的结构的constexpr默认构造函数仅在模板化时有效
- 通过写入全局llvm的地址从执行引擎外部初始化全局llvm值有效吗
- 在CUDA中有效初始化共享内存数组