2014-09-17 4 views
3

클래스에 소멸자와 오버로드 delete을 둘 다 목적으로하는 것은 정확히 무엇입니까?소멸자 대 오버로드 삭제

두 가지 시나리오 중 어떤 시나리오를 사용해야합니까?

답변

4

당신과 함께 객체를 할당 할 때 new 표현처럼 :

X *x = new X(); 

그것은 기본적으로 두 개의 별도의 일을 :

void *temp = operator new(sizeof(X)); 
X *x = new(temp) X; 
: 그 다음 거의 비슷가 메모리에서 개체를 생성, 일부 메모리를 할당

첫 번째는 그냥 원시 메모리 블록을 할당합니다. 두 번째 단계는 원시 메모리 블록을 가져 와서 그 안에 객체를 만듭니다.

delete x; 

... 같은 거의 비슷하다 :

는 대략 반대는 개체를 삭제하면 어떻게

x->~X(); 
operator delete(static_cast<void *>(x)); 

그래서, 운영자가 새로운 연산자 단지 거래를 삭제 원시 메모리 할당 및 해제. 생성자와 소멸자 그냥은 이미 할당 된 메모리에있는 객체를 만들고 파괴하는 것을 처리합니다. 소멸자가 실행되어 일부 메모리에서 객체를 삭제 한 후 operator delete을 사용하여 메모리 자체를 비울 수 있습니다.

기본적으로 모든 유형의 개체를 할당하는 데 사용되는 operator newoperator delete의 글로벌 쌍이 하나 있습니다. 원하는 경우이를 대체 할 수 있습니다. 특정 클래스 (고정 멤버 함수)에 대해 operator newoperator delete을 제공 할 수도 있습니다. 이 경우 해당 함수는 해당 클래스의 객체에 대한 메모리 관리에만 사용됩니다. 이것은 매우 작은 클래스와 같은 것에 특히 유용하며,이 클래스의 많은 수의 오브젝트를 할당하려고합니다. 대부분의 메모리 관리자는 매우 작은 수의 매우 작은 항목을 처리 할 때 특히 효율적이지 않으므로이 경우 오버로드는 메모리 사용을 상당히 향상시킬 수 있습니다.

또한 개체 배열을 할당하거나 사용하지 않을 때 사용되는 operator new[]operator delete[]이 있습니다. operator new[]은 할당 할 바이트 수만 전달되고 operator delete은 그냥 원시 메모리 블록을 통과하여 해제됩니다. 이러한 오버로드를 결정했다면, 주로 더 큰 메모리 블록에 사용하고 적절히 최적화하는 것으로 가정 할 수 있지만 비 어레이 버전과의 유일한 차이점입니다.

일반적으로 배열을 할당하는 데는 new을 사용하지 않는 것이 좋습니다. 이러한 배열은 전혀 관련이 없습니다. 그리고 아니요, std::vector<T>과 같은 것을 만들면 할당자가 사용할 수 없거나 사용할 수 없습니다.글쎄, 만약 당신이 시스템을 완전히 철저히 학대하지 않았다면, std::vector과 함께 사용하기 위해 할당자를 생성 할 수 있습니다. 할당을 관리하기 위해 new char[size]을 사용했는데, 그 중 하나를 사용 하겠지만, 누구나 그렇게 할 수 있다고 상상해보십시오. 어쩌면 C++이 잘 이해되지 않았을 수도 있지만, 요즘에는 괜찮은 코드 기반에서 엄지 손가락처럼 튀어 나와있을 것입니다.


1. 하나의 작은 이상한 : 컴파일러이 항상 당신이 그들을 정의 선언/때 static 키 단어를 사용하지 않도록 경우에도 고정해야한다 "알고있다"는 그들은 수 있습니다 어쨌든 정적.

1

소멸자는 할당 된 자원의 할당 해제 등과 같은 클래스 별 동작을 구현하기위한 것이지 만 delete 연산자를 오버로드하는 것은 클래스에 특정하지 않거나 대상을 지정하지 않는 사용자 정의 메모리 관리를위한 것입니다. 클래스 혼자 as described here. 일반적으로 newdelete을 오버로드 할 필요가 없습니다.

3

그 생성자/소멸자를 실현하고 새로운/삭제 쌍 직교 용도로 사용하면 답은 분명해진다 :

  • 생성자와 소멸자는 클래스 제어를 할 수있는 자원의 획득과 릴리스의 프로세스 귀하를 클래스 소유. 이것들은 객체 자체에 대한 메모리를 포함하지 않습니다.
  • 연산자 newdelete을 사용하면 클래스가 클래스 자체의 인스턴스에 할당 된 메모리를 획득하고 해제하는 프로세스를 제어 할 수 있습니다.

는 생성자와 소멸자의 newdelete 브래킷 호출의 호출 것을 깨닫게하는 것이 중요하다 : new 생성자 전에 발생하며 delete는 소멸자 후에 발생합니다. 소멸자는 객체의 내용을 "라이브"로 처리 할 수 ​​있지만 연산자 delete은이를 "작동 불능"으로 처리해야합니다. 특히 어떤 멤버를 참조하려고하거나 클래스의 멤버 함수를 delete에서 호출하려고하면 정의되지 않습니다.

이제 답은 분명해야합니다. 프로그램에서 제어하려는 내용에 따라 둘 중 하나 또는 둘 다를 구현하십시오.

0

소멸자는 스택에 자동 변수로 할당되었는지 또는 연산자 new이있는 힙에 관계없이 클래스 (객체)의 인스턴스를 파괴하는 데 사용됩니다.

newdelete은 코드에서 연산자 newdelete을 사용할 때만 메모리를 할당하는 데 사용됩니다.

newdelete은 정적이며 void (구조화되지 않은) 메모리에서 작동합니다. 그들은 (암시 적 또는 명시 적으로) this을 통해 클래스의 멤버에 액세스 할 수 없습니다. 이 메모리를 객체에 캐스팅하고 초기화/재설정 할 수 있지만이 용도로 사용하기위한 것은 아닙니다.