我需要一个模板函数来调整任何类型的数组的大小。
这是我的尝试:
class CCommon
{
template < typename T >
static void ResizeArray(T* paArray, int iOldSize, int iNewSize, T tInitValue);
}
..
template < typename T >
void CCommon::ResizeArray(T* paArray, int iOldSize, int iNewSize, T tInitValue)
{
T* paTmpArray = new T[iOldSize];
for(int i = 0; i < iOldSize; i++)
{
paTmpArray[i] = paArray[i];
}
delete [] paArray;
paArray=new T[iNewSize];
for(int i=0; i < iNewSize; i++)
{
paArray[i] = tInitValue;
}
for(int i = 0; i < iOldSize; i++)
{
paArray[i] = paTmpArray[i];
}
delete [] paTmpArray;
}
CCommon文件甚至可以编译,但如果我想使用它,我会得到错误:
Fehler 2错误LNK2019:Verweis auf nichtaufgelöstesexternes符号 “”public:static void __cdecl CCommon :: ResizeArray(INT *,int,int,int)“(?? $ ResizeArray @ H @ CCommon @@ SAXPAHHHH @ Z)” 在Funktion“”public:void __thiscall CWaebi_OBJ ::重新初始化(空)” (?ReInit @ CWaebi_OBJ @@ QAEXXZ)“。CWaebi_OBJ.obj
Fehler 3致命错误LNK1120:1 nicht aufgelösteexterne Verweise。 c:\ PolFlow \ Debug \ Balance_V1.exe 1
这就是我想要的方式:
#include CCommon
SomeFunction
{
..
CCommon::ResizeArray<BOOL>( mTextIndexMask, m_iNumberOfLastTextMaskArray, mTextCount, FALSE );
..
}
有什么问题?
问候主人
答案 0 :(得分:3)
首先,为什么你在地球上使用一些自定义BOOL
类型而不是C ++的内置bool
?
其次,听起来您已将模板实现放在源文件中。 ccommon.h文件中的CCommon::ResizeArray
的实现是否包含在您调用它的位置?如果没有,请将其放在那里(或在其中包含的文件中)。模板需要在头文件中使用它们的整个实现才能工作。您不能在头文件中使用声明,也不能在源文件中使用普通函数和方法。
答案 1 :(得分:1)
我猜您正在尝试在.cpp文件中定义模板成员函数。 这是不好的。模板取决于在实例化时解析的类型,具有生成正确代码的完整定义。 解决方案:将您的定义放在.h。
中包含的.hxx文件中答案 2 :(得分:1)
一旦你在cpp问题(@Tyler McHenry)中修复了模板,你的ResizeArray仍然无法工作,因为你永远不会将新分配的数组返回给调用者。 你要么必须归还它,要么以T **作为论据。
答案 3 :(得分:1)
您似乎尝试将实现放在* .cpp文件中。模板必须在标题中实现。
另一点是你的代码中有一个主要的错误: 您根本不返回新指针,只覆盖参数的本地副本。 这意味着新分配的内存泄漏,之后尝试访问该阵列的任何代码都可能崩溃。
哦,还有另一个提示:为什么要将数组内容复制到临时变量?你可以只分配一个新大小的数组,将内容复制到那个数组中,删除旧数组并返回新指针或使pArray为T **并将新的数组指针指定给那个。
作为最后一点,我建议使用std::copy
和std::fill
操作来复制/填充数组内容,例如:
而不是
for(int i = 0; i < iOldSize; i++)
{
paTmpArray[i] = paArray[i];
}
使用
std::copy(paArray, paArray+iOldSize, paTmpArray);
它导致越来越多的consise代码,并且可能在循环中进行更优化。
所以我建议这样做:
#include <algorithm>
template < typename T >
void CCommon::ResizeArray(T*& paArray, int iOldSize, int iNewSize, T tInitValue)
{
T* paTmpArray = new T[iNewSize];
std::copy(paArray, paArray + std::min(iNewSize, iOldSize), paTmpArray);
delete[] paArray;
if(iNewSize > iOldSize)
std::fill(paTmpArray + iOldSize, paTmpArray + iNewSize, tInitValue);
paArray = paTmpArray;
}
答案 4 :(得分:1)
template < typename T >
void CCommon::ResizeArray(T* paArray, int iOldSize, int iNewSize, T tInitValue)
{
T* paTmpArray = new T[iOldSize];
for(int i = 0; i < iOldSize; i++)
{
paTmpArray[i] = paArray[i];
}
delete [] paArray;
paArray=new T[iNewSize];
for(int i=0; i < iNewSize; i++)
{
paArray[i] = tInitValue;
}
for(int i = 0; i < iOldSize; i++)
{
paArray[i] = paTmpArray[i];
}
delete [] paTmpArray;
}
那不行。调用该函数后,paArray的值不会被更改。你会得到一个内存泄漏,加上paArray会在调用之后指向垃圾。 此外,您不需要使其成为静态类函数。使用模板功能就足够了。 而且你不需要临时阵列。
使用类似的东西:
#include <stdio.h>
template <typename T> void resizeArray(T*& arr, int oldSize, int newSize, const T initVal){
T* newArray = new T[newSize];
for (int i = 0; (i < oldSize)&&(i<newSize); i++)
newArray[i] = arr[i];
for (int i = oldSize; i < newSize; i++)
newArray[i] = initVal;
delete[] arr;
arr = newArray;
}
int main(int argc, char** argv){
const int startSize = 26, newSize = 42;
int* p = new int[startSize];
for (int i = 0; i < startSize; i++)
p[i] = i;
resizeArray(p, startSize, newSize, 87);
for (int i = 0; i < newSize; i++)
printf("%d\n", p[i]);
delete[] p;
return 0;
}
或者这个:
#include <stdio.h>
#include <algorithm>
template <typename T> void resizeArray(T*& arr, int oldSize, int newSize, const T initVal){
T* newArray = new T[newSize];
std::copy(arr, arr+std::min(oldSize, newSize), newArray);
if (oldSize < newSize)
std::fill(newArray+oldSize, newArray+newSize, initVal);
delete[] arr;
arr = newArray;
}
int main(int argc, char** argv){
const int startSize = 26, newSize = 42;
int* p = new int[startSize];
for (int i = 0; i < startSize; i++)
p[i] = i;
resizeArray(p, startSize, newSize, 87);
for (int i = 0; i < newSize; i++)
printf("%d\n", p[i]);
delete[] p;
return 0;
}
代替。