C++值初始化自定义容器的项
C++ value initialize items of a custom container
让我们以自定义vector
实现为例:
template<typename Object>
class myVector {
public:
explicit myVector(int size = 0) :
_size{ size },
_capasity{ size + SPARE_CAPACITY }
{
_buff = new Object[_capasity];
if (_size > 0) {
for (int i = 0; i < _size; i++) {
//_buff[i] = 0;
}
}
}
// more code
private:
Object * _buff = nullptr;
int _size;
int _capasity;
};
所以我的问题是,myVector
如果我将其初始化为:
int main() {
myVector<int> v02(5);
}
在这里,它包含 5 个int
值,所以我需要它全为零;与其他类型相同。我注释掉了_buff[i] = 0;
,因为它特定于int
.请给我一些提示。
它就像
for (int i = 0; i < _size; i++)
_buff[i] = Object{};
或者,您可以摆脱循环并在此处添加一对{}
(或()
):
_buff = new Object[_capasity]{};
// ^^
但是,正如@bipll所指出的,此选项将值初始化所有_capasity
对象,而不是前_size
对象。
另外,请注意,如果你想模仿std::vector
的行为,你需要分配原始存储(可能是std::aligned_storage
)并手动调用构造函数(通过放置新)和析构函数。
如果Object
是类类型,则_buff = new Object[_capasity];
为所有_capasity
对象调用默认构造函数,而不是像std::vector
那样为前_size
对象调用默认构造函数。
请注意,当调用时
_buff = new Object[_capasity];
(顺便说一句,你为什么要把这个初始化从初始化列表中移到构造函数体中?)你已经有了默认初始化的_capasity
对象。默认初始化在这里具有以下效果:虽然标量类型的元素将保持未初始化状态(并从中读取 UB),但对于已经调用_capasity
构造函数的类类型。
为避免不必要的构造,您有以下可能的选项:
使用 std::aligned_alloc 分配未初始化的内存:
explicit myVector(std::size_t size = 0) : size_{ size } , capacity_{ size + SPARE_CAPACITY } , buff_{std::aligned_alloc(alignof(Object), _capacity)} { if(!buff_) throw std::bad_alloc(); if(size) new (buff_) Object[size]{}; // empty braces answer your original query }
请记住,当向量增长时,
buff_
应该再次aligned_alloc
(对于平凡类型可以std::realloc()
ed),并且在析构函数中它应该std::free()
d — 在此之前size_
它里面的对象应该被破坏(显式调用~Object()
)。将
buff_
的类型更改为更简单但正确对齐的类型:using Storage = std::aligned_storage_t<sizeof(Object), alignof(Object)>; Storage *buff_; Object *data_ = nullptr; public: explicit myVector(std::size_t size = 0) : size_{ size } , capacity_{ size + SPARE_CAPACITY } , buff_{new Storage(_capacity)} { if(size) data_ = new (buff_) Object[size]{}; }
同样,在析构函数中,对象应该手动销毁,但这次
buff_
可以简单地delete[]
之后。
- C++类中的类作为自定义向量(如何初始化?
- (C++)我的自定义数组无法初始化(编译错误)
- thread_local静态成员模板定义:初始化失败,GCC
- 如何使用自定义比较器初始化类数据成员,该成员是 std::set
- 初始化自定义类型构造函数的数组
- 自定义初始化数组与 std::make_unique
- 使用没有默认构造函数的类/类型初始化自定义容器
- 为什么初始化列表中的自定义参考不是错误
- 使用 C++ 中的自定义元素进行 Const 结构初始化
- 在类构造函数中初始化自定义结构对象的正确方法
- C++具有自定义初始化的静态调度
- 没有用于初始化我的自定义分配器的匹配构造函数
- 如何为自定义模板化迭代器实现 std::d istance()
- 导入错误:动态模块未定义初始化函数
- 自定义结构化存储 IPropertySetStorage
- C++ - 如何在自定义模板化数据容器中的迭代器上使用 advance() 启用 ADL
- 有没有一种标准的方法可以在初始化阶段运行一些代码并定义初始化的顺序
- C++,为什么我不能把带有参数的类构造函数的定义-初始化列表放在类声明之外
- 是否需要在头文件中定义初始化列表
- 数组成员是否可以自引用初始化