首页 > 解决方案 > 如何在不需要多个新运算符的情况下编写此代码?

问题描述

我有一个通用代码template <class T>,我希望它可以在不需要T() 复制构造函数的情况下工作,我有这个:

template <class T>
SortedList<T>::SortedList(const SortedList<T>& list):
  data(new T*[list.max_size])
 ,size(list.size)
 ,max_size(list.max_size)
 {
     for (int i = 0; i < size; i++)
     {
         T* new_element=new T(*(list.data[i]));//my problem
        data[i]=new_element;
     }
 }

它工作正常,我没有任何 valgrind 错误或任何类型的错误 我了解到,在您的代码中包含多个不是很好的编码new,所以我想编写一个没有new so的代码我试过这个:

T* new_element=& T(*(list.data[i]));

这里有一个错误:取临时地址

有谁知道我现在该怎么办?

标签: c++genericscoding-stylenew-operatorcopy-constructor

解决方案


如果你这样做:

template <class T>
SortedList<T>::SortedList(const SortedList<T>& list):
  data(new T*[list.max_size])
 ,size(list.size)
 ,max_size(list.max_size)
 {
     for (int i = 0; i < size; i++)
     {
         T* new_element=new T(*(list.data[i]));
        data[i]=new_element;
     }
 }

您正在复制 other 的所有元素SortedList<T>。我不确定你从哪里听到的:

我了解到,在您的代码中包含多个新内容并不是好的编码。

远离动态分配并使用预编码容器是一种很好的做法从 的声音SortedList,我会说你想要一个std::set

如果您的容器可以使用其他容器的元素,您可以这样做:

template <class T>
SortedList<T>::SortedList(const SortedList<T>& list):
  data(new T*[list.max_size])
 ,size(list.size)
 ,max_size(list.max_size)
 {
     for (int i = 0; i < size; i++)
     {
         T* new_element= list.data[i];
        data[i]=new_element;
     }
 }

这可能会带来一些问题,因为如果您修改第一个SortedList<T>元素,它会修改第二个元素,所以您可能不想这样做。

你不能这样做的原因:

T* new_element=& T(*(list.data[i]));

是因为*list.data[i]是一个临时变量,一旦退出for循环的当前迭代,它就会被破坏。如果你取它的地址,一旦你试图修改它,你会得到一个错误,因为该元素不再存在。(它已被破坏。)我建议您暂时保持代码不变,或者更好的是,使用不同的容器。

这个问题的另一个答案建议使用这个:

std::memcpy(data, list.data, list.size * sizeof(T))

正如@AndyG 所说,这个问题是:

必须非常小心这样的事情。它只适用于普通可重定位类型,而不适用于泛型 T。

另一个答案也建议做std::copy。这可能适用于您的目的,因为它更高级别,并且new在幕后完成所有工作。要使用它,您可以这样做:

std::copy(list.data[0], list.data[list.size-1], data[0]);

推荐阅读