调整阵列模板的大小

时间:2010-07-30 12:12:01

标签: c++

我需要一个模板函数来调整任何类型的数组的大小。

这是我的尝试:

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 );
..
}

有什么问题?

问候主人

5 个答案:

答案 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::copystd::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;
}

代替。