我相信这是一个简单的问题,答案可能并不简单。
代码如下:
template<typename T>
T* copy(T* original, int size) {
T* result = new T[size];
// At this point the default constructor of all new T objects have been called.
for(int i = 0; i < size; ++i) {
// This will call the assignment operator= on all new T objects
result[i] = original[i];
}
return result;
}
问题:
是否有一种方法可以使用T的复制构造函数来初始化新分配的内存,而不是先使用默认构造函数,然后再使用赋值运算符?
目的是使用T的复制构造函数将每个元素复制到新数组中的类似元素。
我想可以通过使用malloc
分配内存,然后为每个元素调用复制构造函数来实现此目的,但我不知道如何实现。
这是我想像中的示例解决方案。如果这是正确的或这是我们能得到的最好的结果,请告诉我。或提出更好的解决方案:
template<typename T>
T* copy(T* original, int size) {
T* result = malloc(sizeof(T)*size);
// At this point the default constructor of all new T objects have been called.
for(int i = 0; i < size; ++i) {
T t(original[i]);
memcpy(result+i*sizeof(T), &t, sizeof(T));
}
return result;
}
注意:为了简化起见,使用了原始指针。
注意2:我不需要向量。该模式将用于复制更复杂对象的基础数据结构。
答案 0 :(得分:3)
您将不得不通过任何其他方式分配内存,但是请记住size * sizeof(T)
可能会溢出。 std::allocator
会解决这个问题。
使用std::uninitialized_copy
/ std::uninitialized_copy_n
执行复制:
template<typename T>
T* copy(T* original, int size) {
std::allocator<T> alloc;
T* result = alloc.allocate(size);
try {
std::uninitialized_copy_n(original, size, result);
} catch (...) {
alloc.deallocate(result, size);
throw;
}
return result;
}
稍后,您可以使用std::destroy
/ std::destroy_n
销毁它们并释放内存:
template<typename T>
void destroy(T* ptr, int size)
{
std::destroy_n(ptr, size);
std::allocator<T>().deallocate(ptr, size);
}
这应该可行,除非您需要能够使用操作符delete[]
删除它们-在这种情况下,没有解决方案。
如果要实现自定义容器,则可以像标准容器一样使用模板分配器:
template<typename T, typename Allocator = std::allocator<T>>
struct container
{
[[no_unique_address]] Allocator allocator;
...
};
答案 1 :(得分:0)
对于new
运算符,我不这么认为。
但是是。称为std::vector
:
template<typename T>
std::vector<T> copy(T* original, int size) {
return std::vector<T>{original, original + size};
}
由于您不遵循RAII并使用拥有的原始指针,因此您的代码不是无内存泄漏的,所以不要这样做!正确使用C ++。