如何在不需要多个新操作员的情况下编写这段代码?
how to write this code without the need of more than one new operator?
我有一个带有 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
的代码
所以我尝试了这个:
T* new_element=& T(*(list.data[i]));
此处出现错误:获取临时地址
有谁知道我现在该怎么办?
如果你这样做:
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;
}
}
您正在复制另一个 SortedList<T>
的所有元素。我不确定你是从哪里听到的:
I have learned that it is not good coding to have more than one new in your code.
远离动态分配并使用预编码容器是一种很好的做法。从 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 所说:
Gotta be really careful with something like this. It will only work for trivially relocatable types, not generic T.
另一个回答也建议做std::copy
。这可能适合您的目的,因为它是更高级别的,并且在幕后使用 new
完成所有工作。要使用它,您可以这样做:
std::copy(list.data[0], list.data[list.size-1], data[0]);
我有一个带有 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
的代码
所以我尝试了这个:
T* new_element=& T(*(list.data[i]));
此处出现错误:获取临时地址
有谁知道我现在该怎么办?
如果你这样做:
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;
}
}
您正在复制另一个 SortedList<T>
的所有元素。我不确定你是从哪里听到的:
I have learned that it is not good coding to have more than one new in your code.
远离动态分配并使用预编码容器是一种很好的做法。从 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 所说:
Gotta be really careful with something like this. It will only work for trivially relocatable types, not generic T.
另一个回答也建议做std::copy
。这可能适合您的目的,因为它是更高级别的,并且在幕后使用 new
完成所有工作。要使用它,您可以这样做:
std::copy(list.data[0], list.data[list.size-1], data[0]);