Program Club

가상 소멸자는 상속됩니까?

proclub 2020. 10. 19. 13:04
반응형

가상 소멸자는 상속됩니까?


가상 소멸자가있는 기본 클래스가있는 경우. 가상 소멸자를 선언하는 파생 클래스도 있습니까?

class base {
public:
    virtual ~base () {}
};

class derived : base {
public:
    virtual ~derived () {} // 1)
    ~derived () {}  // 2)
};

구체적인 질문 :

  1. 1)과 2)가 같은가요? 2) 기반으로 인해 자동으로 가상입니까, 아니면 가상 성을 "중지"합니까?
  2. 파생 된 소멸자는 할 일이없는 경우 생략 할 수 있습니까?
  3. 파생 된 소멸자를 선언하는 가장 좋은 방법은 무엇입니까? 가상, 비가 상으로 선언하거나 가능하면 생략 하시겠습니까?

  1. 예, 동일합니다. 가상을 선언하지 않는 파생 클래스는 가상이되는 것을 막지 않습니다. 사실, 메서드 (소멸자 포함)가 기본 클래스에서 가상 인 경우 파생 클래스에서 가상이되는 것을 중지 할 방법이 없습니다. > = C ++ 11 final에서는 파생 클래스에서 재정의되는 것을 방지하는 데 사용할 수 있지만 이것이 가상이되는 것을 막지는 않습니다.
  2. 예, 파생 클래스의 소멸자는 할 일이 없으면 생략 할 수 있습니다. 그리고 가상 여부는 중요하지 않습니다.
  3. 가능하면 생략하겠습니다. 그리고 virtual명확성을 위해 파생 클래스의 가상 함수에 대해 항상 키워드를 다시 사용합니다 . 사람들은 함수가 가상이라는 것을 알아 내기 위해 상속 계층 구조까지 올라갈 필요가 없습니다. 또한 클래스가 복사 또는 이동 생성자를 선언 할 필요없이 복사 가능하거나 이동할 수있는 경우 모든 종류의 소멸자를 선언하면 (으로 정의하더라도 default) 원하는 경우 복사 및 이동 생성자와 할당 연산자를 선언해야합니다. 컴파일러가 더 이상 당신을 위해 넣지 않을 것입니다.

항목 3에 대한 작은 요점으로, 소멸자가 선언되지 않은 경우 컴파일러가 기본값 (여전히 가상)을 생성한다는 주석이 지적되었습니다. 그리고 그 기본값은 인라인 함수입니다.

인라인 함수는 잠재적으로 더 많은 프로그램을 프로그램의 다른 부분의 변경 사항에 노출하고 공유 라이브러리에 대한 이진 호환성을 까다롭게 만듭니다. 또한 커플 링이 증가하면 특정 종류의 변경에 대해 많은 재 컴파일이 발생할 수 있습니다. 예를 들어 가상 소멸자에 대한 구현을 정말로 원한다고 결정한 경우이를 호출 한 모든 코드를 다시 컴파일해야합니다. 클래스 본문에서 선언 한 다음 .cpp파일 에서 비어있는 것으로 정의한 경우 다시 컴파일하지 않고 변경할 수 있습니다.

제 개인적인 선택은 가능하면 생략하는 것입니다. 내 생각에 그것은 코드를 복잡하게 만들고 컴파일러는 때때로 빈 구현에 대한 기본 구현으로 약간 더 효율적인 일을 할 수 있습니다. 그러나 당신이 잘못된 선택을하는 제약이있을 수 있습니다.


가상 멤버 함수는이 함수의 오버로드를 암시 적으로 가상으로 만듭니다.

따라서 1)의 가상은 "선택 사항"이며, 기본 클래스 소멸자는 가상이므로 모든 하위 소멸자도 가상으로 만듭니다.


  1. 소멸자는 모든 방법과 마찬가지로 자동으로 가상입니다. 메소드가 C ++에서 가상이되는 것을 중지 할 수 없습니다 (이미 가상으로 선언 된 경우 즉, Java에서 '최종'에 해당하는 것이 없음).
  2. 예, 생략 할 수 있습니다.
  3. 이 클래스를 하위 클래스로 만들려는 경우 가상 소멸자를 선언합니다. 다른 클래스를 하위 클래스로 지정하는지 여부에 관계없이 필요하지 않더라도 가상 메서드를 계속 선언하는 것을 선호합니다. 상속을 제거하기로 결정한 경우 하위 클래스가 계속 작동합니다. 그러나 나는 이것이 단지 스타일의 문제라고 생각합니다.

1 / 예 2 / 예, 컴파일러에 의해 생성됩니다. 3 / 가상으로 선언할지 여부는 재정의 된 가상 멤버에 대한 규칙을 따라야합니다. IMHO, 좋은 인수가 두 가지 모두 있습니다. 하나를 선택하고 따르십시오.

가능하면 생략하고 싶지만 선언하도록 유도 할 수있는 한 가지가 있습니다. 컴파일러에서 생성 한 컴파일러를 사용하면 암시 적으로 인라인됩니다. 인라인 멤버 (예 : 동적 라이브러리)를 피하고 싶을 때가 있습니다.

참고 URL : https://stackoverflow.com/questions/2198379/are-virtual-destructors-inherited

반응형