2017-12-16 3 views
2

을 삭제 사용자 정의 호출하는 방법을 사용자 정의 삭제 [] 연산자 :내가 가진 운영자

void operator delete[](void *ptr, char const* file, int line) noexcept {...} 

내가 전화를 시도, 그것은 단순한는 나의 정의 연산자 [] (무효 *의 PTR)을 삭제 호출

char *b = new char[256]; 
delete[] b, __FILE__, __LINE__; 

컴파일되었지만 사용자 지정 운영자 권한으로 문의 했습니까?

답변

3

delete 표현식을 사용하면 기본값 operator delete(void*)이 호출됩니다. 배열 용도와 비슷합니다. 언어에 의해 operator delete()이 오버로드 된 유일한 경우는 일치 항목 operator new()이 호출 된 후 개체의 생성자에 의해 예외가 throw되는 경우입니다.

사용자 정의를 사용하는 경우 operator new()는, 즉, new(a, b) T(...) 같은 일부 배치 구문을 사용하여 수동으로 오브젝트를 파괴하고 해당 메모리를 해제해야합니다 :

T* ptr = new(__FILE__, __LINE__) T(args); 
// ... 
ptr->~T(); // destroy the object 
operator delete(ptr, __FILE__, __LINE__); 

교체 또는 "정상"오버로드 operator new()/operator delete(), 즉 서명

void* operator new(std::size_t) 
void operator delete(void*) 

(및 대응하는 어레이 형태) 중 어느 하나, 즉, 글로벌 버전을 대체 또는 클래스 고유의 과부하를 사용함으로써, correspo static 구성원에서 소멸자 및 operator delete()delete 표현식에 의해 호출됩니다.

+1

"수동으로 개체를 파괴하고 해당 메모리를 해제해야합니다."아니요. 클래스의 일반적인'operator delete()'(할당 해제 함수)를 구현하고'operator delete' 배치에서 호출하면됩니다. 그런 다음'delete' 표현식이 소멸자를 호출하도록합니다. –

+0

@ Cheersandhth.-Alf : 대체 버전의 경우에만 해당되며 과부하의 경우는 아닙니다 ('std :: nothrow' 변형 제외). 인수를'new' 표현식에 전달하면 내 대답에 명시된대로 수동으로 객체를 릴리스해야합니다. –

+0

"대체 버전"은 클래스의 오버로드를 의미하고 "오버로드"는 전역 네임 스페이스의 함수라는 것을 의미합니다. 미안, 나는 그걸 생각하지 않았다. 여전히 클래스 고유의 할당 함수에는 동일한 'new'표현식 구문이 사용됩니다. 그래서 암묵적인 보편적 양화와 함께 "당신이 사용한다면 ..."파라가 잘못되었습니다. –

1

delete[] b, __FILE__, __LINE__; 

은 ... 쉼표 표현이 아닌 배치 delete 함수의 호출이다.

표현식을 delete 표현식으로 호출하기위한 구문은 delete 함수 (할당 해제 함수)로 작성하는 구문이 없습니다.

이것의 목적은 블록이 삭제 될 소스 코드의 위치를 ​​기록하거나 검사하는 것입니다 가정하면, 할당 된,이 같은 것을 수행 할 수 있습니다

#include <stddef.h>  // size_t 
#include <type_traits> // std::aligned_storage 
#include <iostream> 
#include <memory>  // std::unique_ptr 
#include <new>   // ::new() 

namespace my{ 
    using std::clog; 
    using std::aligned_storage; 

    using Byte = unsigned char; 

    struct Sourcecode_location 
    { 
     char const*  file; 
     int    line; 
    }; 

    constexpr size_t info_size = sizeof(Sourcecode_location); 
    constexpr size_t info_align = alignof(Sourcecode_location); 

    auto location_info_ptr(void* const p_array, size_t const size) 
     -> Sourcecode_location* 
    { 
     const size_t n = ((info_align - 1) + size)/info_align; 
     return reinterpret_cast<Sourcecode_location*>(
      reinterpret_cast<Byte*>(p_array) + n*info_align 
      ); 
    } 

    class Foo 
    { 
     using This_class = Foo; 

     static void report_delete_of(void* ptr, Sourcecode_location const& loc) 
     { 
      clog << "Foo[] " << ptr << " deleted, was allocated at " << loc.file << "(" << loc.line << ")\n"; 
     } 

     static void deallocate_array(void* p) { ::operator delete[](p); } 

    public: 
     auto operator new[](size_t const size) 
      -> void* 
     { return This_class::operator new[](size, "<unknown>", 0); } 

     // If this function is defined it's called instead of the one after here: 
     // void operator delete[](void* const ptr) 

     void operator delete[](void* const ptr, size_t const size) 
      noexcept 
     { 
      clog << "(The size of the following was " << size << " bytes.)\n"; 
      report_delete_of(ptr, *location_info_ptr(ptr, size)); 
      deallocate_array(ptr); 
     } 

     auto operator new[](size_t const size, char const* const file, int const line) 
      -> void* 
     { 
      const size_t n = ((info_align - 1) + size)/info_align; // To cover array. 
      void* const p = ::operator new[](n*info_align + info_size); 
      ::new(location_info_ptr(p, size)) Sourcecode_location{ file, line }; 
      clog << "new Foo[] " << p << " of size " << size << " at " << file << "(" << line << ")\n"; 
      return p; 
     } 

     // Called by construction failure in a placement new expression: 
     void operator delete[](void* const ptr, char const* const file, int const line) 
      noexcept 
     { 
      clog << "(The following array's size was not given)\n"; 
      report_delete_of(ptr, {file, line}); 
      deallocate_array(ptr); 
     } 

    public: 
     ~Foo() {} // Without this MSVC 29017 provides wrong size to deallocation function. 

     Foo() {} 
    }; 
} // namespace my 

auto main() 
    -> int 
{ 
    using namespace std; 

    auto p = unique_ptr<my::Foo[]>{ new(__FILE__, __LINE__) my::Foo[3] }; 
    clog << "\n"; 
} 

일반적인 출력 :

 
new Foo[] 0x3aa08 of size 7 at a.cpp(89) 

(The size of the following was 7 bytes.) 
Foo[] 0x3aa08 deleted, was allocated at a.cpp(89)