기본 생성자의 존재에 따라 연산자 delete ()가 삭제되면 연산자 new ()는 다르게 동작합니다.


17

new () 연산자를 사용하여 클래스 C의 새 객체를 만들면 여기에 오류가 발생합니다.

class C
{
public:
    C() {}
    virtual ~C() {}

    void operator delete(void*) = delete;
};


int main()
{
    C* c = new C;
}

C2280: 'void C::operator delete(void *)': function was explicitly deleted

내가 바꿀 때 C() {}C() = default; 또는 컴파일러 (내가 가진 동일한 효과를 가지고 있다고 생각합니다 기본 생성자를 삽입하도록 줄을 제거 = default), 코드는 컴파일하고 실행합니다.

컴파일러 생성 기본 생성자와 사용자 정의 기본 생성자의 차이점은 무엇입니까?

이 게시물에 힌트가 있지만 소멸자가 가상이기 때문에 여기에 C 클래스 (사용자 제공 생성자 없음)가 사소하지 않습니다.

최신 Visual Studio C ++ 17로 컴파일되었습니다.


3
확실하지 않지만 차이점은 기본 생성자가 다음과 같습니다noexcept
Sebastian Redl

1
g ++로 재생할 수 없습니다. operator delete()생성자가 수동으로 작성되는지 암시 적으로 생성되는지에 관한 유사한 진단 . new식에 의해 예외가 발생할 수 있으므로 컴파일러가 액세스해야합니다 operator delete().
피터

@SebastianRedl 맞아 추가 noexcept하면 코드가 컴파일되지만 어떻게 ...?
yeshjho

1
@Peter 예외는 생성자 만 처리 할 수 ​​있으므로 noexceptSebastianRedl에서 언급 한 경우 호출을 operator delete포함 할 필요가 없습니다. 또한 g ++은 소멸자가 가상 ​​인 경우에만 불평합니다. 그렇지 않으면 생성자가 던지더라도 항상 컴파일됩니다.
호두

@LeDYoM 귀하의 링크는 IP 주소 파싱에 관한 것이며 질문과 관련이없는 것 같습니다. 잘못된 링크를 게시 했습니까?
LF

답변:


17

컴파일러 생성 기본 생성자와 사용자 정의 기본 생성자의 차이점은 무엇입니까?

newexpression은 해당 항목 operator new을 호출 한 다음 생성자를 호출합니다. 생성자가 예외를 throw하면 해당 new표현식 operator new을 호출하여 (메모리 누수를 피하기 위해) 효과를 취소해야합니다 operator delete. 후자가 삭제되면 newexpression을 호출 할 수 없으므로 컴파일러가 생성 error: use of deleted function 'static void C::operator delete(void*)'됩니다.

noexcept생성자 아마도 대응은, 따라서, 예외를 발생 수 operator delete그것이 호출되지 않으므로 불필요 new식. default사소한 클래스의 생성자도이다 noexcept생성자입니다. operator delete특수 스칼라 삭제 소멸자 ( delete기본 클래스 포인터를 통한 표현식 을 가능하게하는 구현 세부 사항 )가 호출 되므로 가상 소멸자의 존재는 삭제되지 않아야 합니다 operator delete.

컴파일러 operator deletenew표현식 으로 호출 할 수없는 경우에도 컴파일러를 삭제하지 않아야하는지 여부는 C ++ 표준에 의해 지정되지 않은 것 같습니다 . gcc그러나, 해당 호출하지 않는 것 operator deletenew이 경우 전혀 표현을 deleted는 (게시 된 버그 리포트를 ).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.