2011-03-25 3 views
1

standart 템플릿 트리 구조를 구현 중이며 작은 문제가 발생했습니다.어떤 방법으로 포인터를 삭제할 수 있습니다 : 삭제/삭제 []/무료?

각 노드가 일부 데이터에 대한 포인터를 보유한다는 아이디어. 나중에 요소를 올바르게 삭제하려면 배열에 대한 단일 포인터인지 포인터인지를 알아야합니다. 내 tree->ReleaseMemory() 방법의 내부

이 코드를 가지고 :

_destructionMethod이 노드의 초기화시에 설정 한
if (node->_data != NULL) { 

     switch (_destructionMethod){ 

     case tree_delete: 
      delete node->_data; break; 
     case tree_deleteList: 
      delete [] node->_data; break; 
     case tree_free: 
      free(node->_data); break; 

    } 


} 

. 초기화 중에 특수 변수에 미리 정의하지 않고 올바른 소멸자를 선택할 수있는 방법이 있습니까?

감사합니다.

+0

필자는 이것이 스마트 포인터로 작업하는 방법을 이해할 수있는 좋은시기라고 생각합니다. 선택적으로 객체 래핑으로 돌아갈 것입니다.감사합니다. – kirbo

답변

1

전혀 사용하지 마십시오. C++ 0x 또는 부스트의 shared_ptr과 같은 스마트 포인터를 사용하거나 옵션이 아니면 C++의 auto_ptr을 사용하십시오. 개체가 두 개 이상일 수 있다면 std::vector을 사용해보십시오.

수동 리소스 관리가 복잡하고 옳지 않습니다.

+1

가능할 수도 있지만 상황에 따라 원시 포인터/데이터를 사용하는 것이 유효 할 수도 있습니다. 하지만 그렇다면 - 처음부터 할당을 처리하지 않으면 릴리스를 구현해야한다고 생각하지 않습니다. – stefan

+0

그리고 C++ 0x –

+0

에서'boost :: checked_array_deleter'와'std :: default_delete '의 존재에 주목하고 std :: auto_ptr <>을 STL 컨테이너와 함께 사용하지 마십시오 : http://stackoverflow.com/questions/111478/why-it-wrong-to-use-stdauto-ptr-with-stl-containers – rturrado

4

먼저 기본 :

int *p = new int; 
int *a = new int[10]; 
//... 
delete p; 
delete []a; //note the difference! 

free를 사용하면 malloc으로 메모리를 할당 할 때 :

int *p = (int*)malloc(sizeof(int) * 1); 
int *a = (int*)malloc(sizeof(int) * 10); 
//... 
free(p); 
free(a); //no difference! 

을 이제 당신이 new으로 메모리를 할당 할 때

delete를 사용하는 문제 :

이 내가

policy-based design을 고려 초기화 중에 특수 변수에 미리 정의하지 않고 올바른 소멸자를 선택할 수있는 방법입니다. 즉, 클래스에서 할당 및 할당 해제를 캡슐화하고 코드에서 일관되게 사용하는 allocator을 작성하십시오.

+3

초기화시'_destructionMethod'를 설정 했으므로 질문자가 알고 있다고 확신합니다. 오히려 질문이이 저장된 값의 필요성을 피하기 위해 찾고 있다고 생각합니다. 저장하려는 값을 묻지 않습니다. –

2

아니요, 특정 포인터가 원래 제공 한 할당자를 알아낼 수있는 이식성이 없습니다.

2

할당 방법을 알아보기 위해 포인터를 조사 할 방법은 없지만 할당 된 객체 자체에 자체 파괴를 책임지는 것이 일반적인 관용구입니다. 개체 유형이 모든 클래스 유형이 아닌 것처럼 보입니다. 이렇게하려면이를 래핑해야합니다. 예 :

class destroyable_node 
{ 
    virtual void destroy() = 0; 
}; 

template <typename T> class object_node : public destroyable_node 
{ 
private: 
    T * value_; 

public: 
    // Presumes T is copy-constructable. 
    object_node(T value) : value_(new T(value)) {} 

    operator T&() {return value_;} 
    operator T const &() const {return value_;} 

    void destroy() {delete value_;} 
}; 

template<typename T> class array_node : public destroyable_node 
{ 
private: 
    T * value_; 

public: 
    array_node(T[] value) 
     : value_(new T[ sizeof(value)/sizeof(T) ]) 
    { 
     std::copy(value, value + sizeof(value)/sizeof(T), value_); 
    } 

    operator T*() {return value_;} 
    operator T const *() const {return value_;} 

    void destroy() {delete[] value_;} 
}; 

... 등등.

0

컨테이너가 사용하는 추상 인터페이스를 구현하는 것이 더 좋은 디자인입니다.이 추상 인터페이스는 포인터를 보유하고있는 것을 알 수있는 세 개의 구체적인 하위 클래스로 구성됩니다. 컨테이너는 기본 클래스에서 destroy() 메서드를 호출하고 파생 클래스가 올바른 소멸자를 호출하는 것에 대해 걱정할 수 있습니다.

관련 문제