C++ 调整数组模板大小

C++ 调整数组模板大小,c++,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 i

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

以下是我的尝试:

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 没有外部符号 公共:静态无效\uuu cdecl CCommon::ResizeArrayint *,int,int,int$ResizeArray@H@共同@@SAXPAHHHH@Z 在Funktion public中:void\uu thiscall CWaebi_OBJ::ReInitvoid ?ReInit@CWaebi_OBJ@@QAEXXZ。CWaebi_OBJ.OBJ

Fehler 3致命错误LNK1120:1 nicht 奥夫盖尔斯泰克斯特内酒店 维维斯。c:\PolFlow\Debug\Balance\u V1.exe 1

我想这样称呼它:

#include CCommon

SomeFunction
{
..
CCommon::ResizeArray<BOOL>( mTextIndexMask, m_iNumberOfLastTextMaskArray, mTextCount, FALSE );
..
}
怎么了


关于camelord

,我想您正在尝试在.cpp文件中定义模板成员函数。 这很糟糕。模板依赖于实例化时解析的类型,具有生成正确代码的完整定义。
解决方案:将您的定义放在.hxx文件中,该文件包含在.h中。

我猜您正在尝试在.cpp文件中定义模板成员函数。 这很糟糕。模板依赖于实例化时解析的类型,具有生成正确代码的完整定义。
解决方案:将您的定义放在一个.hxx文件中,该文件包含在.h中。

首先,您到底为什么要使用一些自定义BOOL类型而不是C++的内置BOOL


其次,听起来您已经将模板实现放在了源文件中。CCommon::ResizeArray的实现是否在包含在调用它的位置中的CCommon.h文件中?如果没有,请将其放在那里或包含在其中的文件中。模板需要在头文件中有完整的实现才能工作。你不能像使用普通函数和方法那样在头文件中声明,在源文件中定义。

首先,你到底为什么要使用一些自定义BOOL类型而不是C++的内置BOOL


其次,听起来您已经将模板实现放在了源文件中。CCommon::ResizeArray的实现是否在包含在调用它的位置中的CCommon.h文件中?如果没有,请将其放在那里或包含在其中的文件中。模板需要在头文件中有完整的实现才能工作。你不能像使用普通函数和方法那样在头文件中声明,在源文件中定义。

一旦你在cpp problem@Tyler McHenry中修复了模板,你的ResizeArray仍然无法工作,因为你永远不会将新分配的数组返回给调用者。
要么你必须返回它,要么接受一个T**作为参数。

一旦你在cpp problem@Tyler McHenry中修复了模板,你的ResizeArray仍然无法工作,因为你永远不会将新分配的数组返回给调用者。
要么返回它,要么接受一个T**作为参数。

似乎您试图将实现放在*.cpp文件中。模板必须在标题中实现

另一点是,您的代码中有一个主要错误: 根本不返回新指针,只覆盖参数的本地副本。 这意味着新分配的内存会泄漏,之后试图访问阵列的任何代码都可能崩溃

哦,还有另一个提示:为什么要将数组内容复制到临时变量中?您只需分配一个新大小的数组,将内容复制到该数组中,删除旧数组,然后返回新指针或将pArray设为T**并将新的arraypointer分配给该数组

最后,我建议使用std::copy和std::fill操作来复制/填充数组内容,例如: 而不是

for(int i = 0; i < iOldSize; i++)
{
    paTmpArray[i] = paArray[i];
}
它会导致越来越少的代码,并且可能比在循环中进行更优化

下面是我的建议:

#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;
}

您似乎试图将实现放在*.cpp文件中。模板必须在标题中实现

另一点是,您的代码中有一个主要错误: 根本不返回新指针,只覆盖参数的本地副本。 这意味着新分配的内存会泄漏,之后试图访问阵列的任何代码都可能崩溃

哦,还有另一个提示:为什么要将数组内容复制到临时变量中?您只需分配一个新大小的数组,将内容复制到该数组中,删除旧数组,然后返回新指针或将pArray设为T**并将新的arraypointer分配给该数组

最后,我建议使用std::copy和std::fill操作来复制/填充数组内容,例如: 而不是

for(int i = 0; i < iOldSize; i++)
{
    paTmpArray[i] = paArray[i];
}
它会导致越来越少的代码,并且可能比在循环中进行更优化

下面是我的建议:

#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;
}
那是行不通的。调用该函数后,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;
}
相反

那是行不通的。调用该函数后,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;
}

相反。

大多数SO用户将无法读取错误消息。“未解析的外部引用”。还有一个.cpp文件中的另一个模板定义。您可能希望通过引用传递指针-与问题无关,但仍然存在错误。此外,您复制的函数比您需要的要多,而且在任何方面都不是异常安全的。只是想知道,错误语言是什么?大多数用户将无法读取错误消息。“未解析的外部引用”。以及.cpp文件中的另一个模板定义。您可能希望通过引用传递指针-与问题无关,但仍然存在一个bug-。而且你的函数是昂贵的,你复制的比你需要的要多,而且在任何方面都不是异常安全的。只是想知道,错误语言是什么?像这样?BOOL*tmpTextIndexMask=新BOOL[iNewSize];forint i=0;istd::copypaTmpArray,paTmpArray+iOldSize,paArray;如果新大小小于旧大小,则将崩溃。如果您的MTEXIDEXMASK是布尔**,并且您使用*MTEXIDEXMASK=。。或者一个傻瓜&然后是的。否则,你仍然有一个bug,你不返回你的值。像这样吗?BOOL*tmpTextIndexMask=新BOOL[iNewSize];forint i=0;istd::copypaTmpArray,paTmpArray+iOldSize,paArray;如果新大小小于旧大小,则将崩溃。如果您的MTEXIDEXMASK是布尔**,并且您使用*MTEXIDEXMASK=。。或者一个傻瓜&然后是的。否则,您仍然存在不返回值的错误。对于新阵列仍然不是异常安全的使用auto_ptr,然后在所有复制成功后释放它。当然,显然不是不能处理阵列的auto_ptr,而是它的阵列版本。对于新阵列,仍然不能例外安全地使用auto_ptr,然后在所有拷贝成功后释放它。显然不是auto_ptr,它不能处理数组,而是它的一个数组版本。