해결된 질문
작성
·
136
·
수정됨
0
상속 관계에 있는 두 클래스, Player 와 Archer 에서
(Player *) player = new Archer() 예시를 들어 주셨습니다.
만약 virtual 소멸자를 사용하지 않은 경우에
delete player; 를 하면 Archer 의 소멸자가 호출되지 않는다는 것을 알게 됐습니다.
Q. delete player; 를 한 경우에 자식 클래스인 Archer의 객체 멤버 변수 등, 객체의 메모리를 반납하고 소멸자를 호출하지 않을 뿐인 건가요? 아니면 Player 클래스의 객체에 해당하는 메모리만 반납하고, Archer 객체의 멤버 변수 등에 해당하는 메모리를 반납하지 않고 소멸자도 호출하지 않는 것인가요?
보여주신 예시 같은 경우에서는 Archer의 멤버 변수 Pet* _pet 이 힙의 Pet 객체를 가리키고 있는데, 소멸자를 호출하지 않아서 힙에 해당하는 메모리를 반납하지 않는다는 것은 이해했습니다. 다만, 이 포인터에 해당하는 메모리도 반납하지 않는 것인지 궁금합니다.
답변 2
0
질문이 모호한데 [멤버 변수 등, 객체의 메모리를 반납한다]는 표현이 애매하지만
느낌적으로 본다면 포인터 타입으로 들고 있으면 아무 것도 하지 않지만,
멤버 변수로 다른 클래스를 (포인터가 아닌채로) 들고 있다면,
그 아이의 소멸자도 같이 호출해줍니다.
이 부분은 테스트를 직접 해보시기 바랍니다.
포인터에 해당하는 메모리도 반납하지 않는다 또한 표현이 애매한데
주소를 가리키는 것이 포인터이고, 해당 주소를 담는 변수는 객체와 함께 날라가지만
원본 객체는 당연히 살아 남아 있습니다.
0
안녕하세요, 인프런 AI 인턴입니다.
elias님의 질문에 대해, virtual 소멸자
와 관련된 C++ 클래스의 상속 구조에서 소멸자가 작동하는 방식에 대해 해설하겠습니다. virtual 소멸자
를 사용하지 않았을 때의 문제에 대한 직접적인 해결 방안을 제시하는 기존 답변을 찾았습니다.
먼저, C++에서는 객체가 소멸될 때 해당 객체의 타입에 따른 소멸자가 호출됩니다. 만약 virtual 소멸자
를 사용하지 않는다면, 베이스 클래스 포인터를 통해 파생 클래스 객체를 삭제할 경우, 파생 클래스의 소멸자가 호출되지 않게 됩니다. 이는 객체가 사용하던 자원이 제대로 해제되지 않아 메모리 누수(memory leak)나 다른 리소스 누수(resource leak)를 일으킬 수 있습니다.
질문하신 내용에 따르면, Player
클래스를 베이스 클래스로하고 Archer
클래스가 파생된 예에서, 베이스 클래스 포인터(Player*
)를 통해 Archer
객체를 삭제(delete player;
)할 경우, Archer
의 소멸자가 호출되지 않으면, Archer
객체가 추가로 관리하던 리소스(예: Pet* _pet
포인터가 가리키는 객체)는 제대로 해제되지 않습니다. 즉, Archer
객체의 멤버 변수뿐만 아니라, 해당 멤버 변수가 가리키는 힙 메모리 등의 자원도 해제되지 않게 됩니다.
이와 관련된 다음 답변이 질문에 도움이 될 것입니다:
virtual 소멸자
를 사용하지 않았을 때 발생할 수 있는 메모리 누수 상황에 대해 설명하고 있습니다. 특히 베이스 클래스의 포인터를 통해 파생 클래스 객체를 삭제할 때 virtual 소멸자
의 중요성을 강조하고 있습니다.저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.