2011-04-01 5 views
2
#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; 
} 

템플릿을 사용하여 메모리를 할당하고 새로운 기능을 사용할 수 있습니까? 그리고 내 실수는?템플릿 및 메모리 할당

+0

어떤 문제가 발생합니까? – sharptooth

+0

왜 std :: vector가 당신을 위해 그것을 할 때 당신은 스스로 배열을 만들고 싶습니까? –

+0

n * n * n의 배열을 만들고 싶습니다. 그리고 이것 모두는 특별한 경우입니다. – ObiSan

답변

3

코드에 잘못된 것이 있습니다. 첫째, 당신은 당신이 뭘 하려는지 뭔가를 할 수 있지만,이 같은 작성해야 : 당신이 (가 CreateArray 내부에 복사 될 a 배열을 전달하지 않아도

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

주, 그 변경 사항은 main 안에 표시되지 않습니다. 템플릿 T*을 반환하도록 템플릿을 정의하십시오. 즉, main()a이 기대하는 템플릿입니다.

+0

당신은'CreateArray (n)'을 놓쳤습니다. – ybungalobill

+0

그래, 맞아. 이 경우 (컴파일러에서 추론 할 수 있습니다) 필요한 경우 확실하지 않지만 완료하도록 추가 할 것입니다. –

+2

@Diego : 컴파일러는 템플릿 인수 공제에 반환 형식을 사용하지 않습니다. – ybungalobill

2

당신은 당신이 할당 할 유형에 포인터을 수용 할 :

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

이 트릭을 할해야합니다.

+0

'템플릿 T * CreateArray (T * & a, int n) { = 새 T [n]; return a; }'- 사소한 수정. – Naszta

+1

@Naszta : 누가 논쟁을 수정하고 싶다고 했습니까? – ybungalobill

+0

ybungalobill. 그 또는 그녀는 분명히 a를 수정하려하지만, 그 방법으로는 작동하지 않으므로 리턴하고 그것을 main()에 직접 할당합니다. 이것이 포인터에 대한 참조를 사용하는 것이 그 또는 그녀는 이해해야합니다. –

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도 좋은 해결책이 될 수 있습니다. 나는 당신이 기억 누출을 만들지 않기 때문에 더 나은 것이라고 생각한다.

+2

당신은 그것을 선호 할지도 모르지만 이제는 다른 의미론을 가진 완전히 다른 프로그램입니다. –

+0

흥미로운 솔루션이지만 컴파일러는 "T * &"표현을 사용하고 변수의 곱셈으로 인식합니까? – ObiSan

+0

@ObiSan : MS 컴파일러가 방금 그것을 받아 들였습니다. 그것은 포인터의 참조입니다. – Naszta

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

쉬운.

이제이 코드를 사용해야합니까? 아니, 아마. 직접 할당보다 실질적인 이점은 없습니다. 그러나 그것을 아는 것은 유용한 관용구입니다.

+0

즉, 메모리를 할당 할 때 템플릿을 분배하는 것이 더 좋습니까? – ObiSan

+0

@ObiSan 일반적으로는 아니지만 위의 코드는 예상치 못한 경우 일 수 있습니다. 하지만 그 외에는 일반적으로 ** 메모리를 모두 할당하지 않아야합니다. C++의 장점은 대부분의 경우 메모리 관리에 대해 걱정하지 않아도된다는 것입니다. 배열의 경우 솔루션은 간단합니다. 동적 메모리 대신 항상'std :: vector'를 사용하십시오. –