2016-12-19 4 views
0

포인터에 관한 사소한 문제가 발생했습니다. 나는 한 줄에서이 작업을 할 수있는 빠르고 쉬운 방법이 싶었로 : 난 그냥 빨리 포인터의 모든 유형을 허용하는 템플릿 방법 간단한 헤더 파일을 설정포인터를 삭제하고 재설정하는 C++ 템플릿 함수

... 
delete pointer; 
pointer = 0; 
... 

합니다.

#ifndef P_DELETE_H 
#define P_DELETE_H 

template <typename T> 
void pDelete(T* pointer) { 
    if (pointer) { 
    delete pointer; 
    pointer = 0; 
    } 
} 

#endif 

그러나 결과는 삭제 된 개체 및 포인터 재설정에 대한 내 기대치를 충족시키지 못합니다. 대신 개체 만 삭제 된 것으로 보였지만 0으로 설정하면 효과가 없습니다 (필요한 경우). 누군가가 나를 위로 가볍게하고이 행동을 설명 할 수 있다면, 나는 그만큼 기뻐할 것입니다!

UPDATE : 대답 설명으로

, 표준 : : unique_ptr 및 표준을 사용하여 :: shared_ptr의이 포인터를 무효로보다 갈 수있는 안전한 방법입니다.

하지만 당신은 정말 요청과 같은 길을 갈해야하는 경우, 다음 코드는 트릭을 할 것입니다 :

template <typename T> 
inline void pDelete(T*& pointer) { 
    if (pointer) { 
    delete pointer; 
    pointer = 0; 
    } 
} 

그러나이 제대로 삭제하고 포인터를 무효화에도 불구하고, 사용하기 일반적으로 안전하지 않은 모든 경우에 (빠른 테스트 결과).

유익한 답변을 보내 주신 모든 분들께 감사드립니다.

+2

함수 인수는 함수 범위에 대해 로컬입니다. 여기에는 포인터가 포함됩니다. 포인터 참조 또는 포인터 포인터를 사용하여 함수 외부의 값에 영향을 주어야합니다. (또는 원시 포인터 사용을 중단하십시오.)이 모든 것을 필요로하지 않을 것입니다. – Biffen

+0

참조 매개 변수가 필요합니다 :'void pDelete (T * & pointer)' –

+0

* 참고 *와 인자 전달 방법에 대해 알고 있습니다 * 참조로 *? –

답변

6

당신이 찾고있는 솔루션입니다 :

delete pointer; 
pointer = nullptr; 

그래, 그냥 라인이 코드를 작성합니다. 실제로 사람들이 코드의 한 줄을 저장하기 위해 실제로 무엇을 알아 내기 위해 찾아야하는지 다른 곳에서 템플릿을 소개 할 이유가 없습니다.

위의 내용은 완벽하게 읽기 쉽고 이해하기 쉽습니다.

+0

그러나 위의 내용은 꽤 이상한 사실을 잊지 마십시오. 삭제 후 포인터를 널링하는 데 도움이되는 경우 자동으로 무효화됩니다. – SergeyA

+2

@ SergeyA 물론 이점이 있습니다. 그것은 일반적으로 당신이 그 이익을 필요로하지 않기 때문에, 자동적으로 무효화되지 않는 이유입니다. – Barry

+0

'일반적으로 혜택이 필요하지 않습니다'- 정확하게. – SergeyA

1

당신이하려는 모든 일이 멍청한 것입니다. 이것이 자동으로 일어나지 않는 이유에 대해 생각해 보셨습니까? 왜 런타임이 삭제 후 포인터를 무효화하지 않는가? C++ 표준위원회가 충분히 똑똑하지 않았기 때문에?

아니요. 시간이별로 없기 때문에. 예, 포인터의이 인스턴스를 무효화합니다. 그러나 포인터가 처음부터 시작된 전체 이유는이 포인터가 다른 곳에 잘 살고 있다는 것입니다. (물론 이에 대한 예외가 있습니다). 결과적으로, 모든 무효화는 포인터의이 인스턴스에 대한 잘못된 액세스입니다. 그러나 다른 인스턴스에는 액세스 할 수 없습니다. 본질적으로, 그것은 당신에게 잘못된 안전감을줍니다.

안전에 대한 잘못된 느낌보다는 자동 포인터 사용을 선택하십시오. std::unique_ptr을 먼저 선택하고, 충분하지 않으면 std::shared_ptr을 입력하십시오.하지만 실제로 필요한지 확인하십시오!

+0

shared_ptr을 QT와 함께 사용하는 방법을 설명 할 수 있다면 지금 바로 사용하십시오. 나는 그것들을 사용하는 것이 더 안전하고 깨끗하다는 것을 알고 있습니다. 그러나 qt 함수를 포함해야 할 필요가있는 곳에서는 저에게 무의미한 것처럼 보입니다. – Migsi

+0

@Migsi, Qt에 대해 많이 알지는 못 하겠지만, 내가 이해하는 한, Qt는 자체 스마트 포인터 기능을 가지고 있습니까? – SergeyA

+1

@Migsi 만약 QT 객체를 다룰 때'delete'를 직접 호출한다면,'std :: unique_ptr'와'std :: shared_ptr'에서 일반적으로 사용되는 것과 같은 패턴이 당신에게 적용되지 않는다고 생각할 이유가 없습니다 상태. – Xirema

1

소유권을 나타 내기 위해 원시 포인터 사용을 중지합니다. 포인터를 통해 객체의 소유권을 가져 오는 경우 std::unique_ptr으로 이동해야합니다.

귀하의 상황은 pointer.reset()입니다.

소유권을 이전하지 않고 다른 코드가 소유 한 개체를 관찰하게하려면 pointer.get()을 사용하여 소유하지 않는 포인터를 가져올 수 있습니다. *pointer을 사용하여 참조를 얻을 수도 있습니다.

원시 포인터를 사용하는 인터페이스를 통해 해당 소유권을 전달해야하는 경우 (나는 당신, Qt를보고 있습니다) pointer.release()을 사용하십시오.

+0

그래서 "QRT에 모든 포인터가 들어갈 것입니다." 또한 QT에서 제공하거나 얻을 수있는 포인터에 대해서도 신경 써야합니까? 설명서는 종종 매우 명확하지 않은 채로 남아 있습니다. – Migsi

+2

원시 포인터를 사용하기 전에 명확하지 않은 경우 누출 또는 이중 삭제 중이었습니다. 그 점에서 아무것도 변하지 않았습니다. Qt는 일반적으로 "부모/자식"관계 뮤 테이터의 포인터를 통해서만 소유권을 이전합니다 – Caleth