模板&内存分配

时间:2011-04-01 12:45:03

标签: c++ templates memory-management new-operator

#include <iostream>

template<class T> T CreateArray(T a, int n)
{
    a = new T [n]; // mistake: double* = double**
    return a;
}

int main()
{
    double* a;
    int n = 5;
    a = CreateArray(a,n);
    return 0;
}

我可以使用模板和新分配内存吗?我的错误是什么?

4 个答案:

答案 0 :(得分:3)

你的代码有些错误。首先,你可以做一些像你想做的事情,但你应该这样写:

template<class T> T* CreateArray(int n)
{
    T* a = new T [n];
    return a;
}

int main()
{
    double* a;
    int n = 5;
    a = CreateArray<double>(n);
    return 0;
}

请注意,您不必传递a数组(它将在CreateArray内复制,并且其更改将在main内不可见)。另请注意,您将模板定义为返回指针T*,这是main() a所期望的。

答案 1 :(得分:3)

所以其他人已经解释了为什么你的代码不起作用以及如何改进它。

现在我将展示如何仍然获取以下代码进行编译 - 并正常工作:

 double* a = CreateArray(5);
 int* b = CreateArray(7);

正如已经提到的,问题在于C ++不仅仅从返回类型推断出模板参数。

您可以通过使上述函数返回一个简单的代理对象来规避此限制。代理对象只有一个操作:(隐式)转换为T*。这是实际分配的地方。

因此CreateArray函数非常简单(模板):

CreateArrayProxy CreateArray(std::size_t num_elements) {
    return CreateArrayProxy(num_elements);
}

至于代理:

struct CreateArrayProxy {
    std::size_t num_elements;

    CreateArrayProxy(std::size_t num_elements) : num_elements(num_elements) { }

    template <typename T>
    operator T*() const {
        return new T[num_elements];
    }
};

简单π。

现在,您应该使用此代码吗?不,可能不是。它没有直接分配的真正优势。但这是一个有用的成语。

答案 2 :(得分:2)

您希望接受指针到您要分配的类型:

template<class T> T* CreateArray(T* a, int n)
{
    a = new T [n];
    return a;
}

这应该可以解决问题。

答案 3 :(得分:2)

我更喜欢保持空指针值为NULL。

#include <iostream>

template<class T> bool CreateArray(T * &a, int n)
{
    if ( a != 0 )
      return false;
    a = new T [n];
    return true;
}

int main()
{
    double* a = 0;
    int n = 5;
    CreateArray(a,n);
    return 0;
}

vector也可能是一个很好的解决方案。我认为这是更好的一个,因为你不会使内存泄漏。

#include <vector>

int main()
{
    std::vector<double> a;
    int n = 5;
    a.resize(n);
    return 0;
}