inflearn logo
강의

Course

Instructor

[MMORPG Game Development with C++ and Unreal Series] Part 1: Introduction to C++ Programming

부모 클래스에서 소멸자를 virtual로 만들어야 하는 이유

825

essenger M

21 asked

0

부모 클래스에서 만약에 가상함수를 한 개라도 정의했으면 가상함수 테이블이 생기고

이때 부모클래스의 가상 함수 테이블을자식 클래스가 고대로 물려받고 이때 만약 그 가상 함수를 오버라이딩 하지 않았다면 가상함수 테이블에서 가르키고 있는 함수 주소 마저 같은걸로 알고 있는데요

그러면 만약 부모클래스 소멸자를 virtual을 붙였다면 부모의 v-table이나 자식의 v-table은 소멸자에 해당하는 함수의 주소를 똑같이 가리키고 있는것이고 부모 클래스의 소멸자를 virtual을 붙이지 않았다면 부모나 자식의 v-table에는 소멸자에 대한 함수정보가 없어서 자식클래스 소멸자에 접근할 수 있는 방법이 없기 때문에  메모리릭이 발생하는것인가요..? 너무 헷갈리고 제가 뭔가 오개념이 있는거 같아서 질문드립니다. 

 

C++

Answer 2

2

Rookiss

 

그러면 만약 부모클래스 소멸자를 virtual을 붙였다면 부모의 v-table이나 자식의 v-table은 소멸자에 해당하는 함수의 주소를 똑같이 가리키고 있는것이고 부모 클래스의 소멸자를 virtual을 붙이지 않았다면 부모나 자식의 v-table에는 소멸자에 대한 함수정보가 없어서 자식클래스 소멸자에 접근할 수 있는 방법이 없기 때문에  메모리릭이 발생하는것인가요..? 

-> 그건 아니구요.
부모 클래스 소멸자에 virtual이 없다고 '항상' 메모리 릭이 일어나는 것은 아닙니다.
우선 부모에 virtual 소멸자가 붙는 경우,
현재 포인터 타입이 아니라 실제 최초로 객체를 만들었을 때 무엇으로 만들었는지에 따라
소멸자가 호출된다고 이해하시면 됩니다. (소멸자 뿐 아니라 다른 가상함수도 마찬가지)
즉 객체 0번째 오프셋에 위치한 vtable 포인터가 런타임에 채워지기 때문에
위 예제에서 우리가 Archer를 GameObject*로 관리하더라도
~Archer()가 덩달이 호출되는 것을 확인할 수 있습니다.
만약 GameObject 소멸자가 virtual이 아닌데
우리가 GameObject* archer = new Archer(); 를 했다면
Archer()가 호출되지 않는 것을 확인할 수 있죠.

위 스샷 3가지 케이스에 대해 심도있게 고민해보시기 바랍니다.
그러면 추가로 알 수 있는 것이, 만약에 ~Archer() 소멸자가 반드시 호출되었어야 했다면
(ex. Archer 클래스 내부에서 관리하는 Pet*을 원래 ~Archer()에서 정리 해줘야 한다거나...)
여기서 메모리 릭이 일어날 수 있겠죠.

 

1

essenger M

저렇게 부모타입으로 만들어놓고 자식 클래스 객체를 호출 할 때 즉 이런 상황일때

Item* item=new Weapon()  인 상황일때 

(Item이 weapon의 부모 클래스 일때)

Item의 소멸자를 가상함수로 만들었으면 type이 item이라도 weapon에 객체를 쫓아가는것이고

그렇지 않으면 결국에는 Item만 쫓아가서 Item의 소멸자만 뿅 실행하고 끝나버려서 메모리릭이 발생한다고 이해하면 맞을까요?? 

0

Rookiss

네 그렇습니다.
Item의 소멸자만 뿅 실행하고 끝나도 딱히 문제가 없는 상황이라면,
위험하지만 당장 버그없이 지나가겠지만,
그게 아니라 뭔가 ~Weapon()에 메모리 정리 코드가 있었다면 조금씩 메모리를 갉아먹겠죠.

0

essenger M

감사합니다 !

visualstudio에서 파일분할관리실습시 설정 문의를 드립니다.

0

541

1

정렬함수 좀 더 확실하게 이해 할 방법이 있을까요?

0

442

1

strcpy() 구현 관련 질문

0

513

1

빌드(망치)를 누르니 이런 오류가 떴습니다. 어떻게 해야 하나요?

0

452

1

클래스 타입의 포인터 질문합니다

0

546

1

입력값을 enum 값에 넣어주는거 이제 막혔나요?

0

497

1

템플릿 특수화 관련 질문

0

384

1

포인터 관련 질문합니다!

0

263

1

Unable to start assembler. Check your settings.

0

830

2

cpu선택

0

539

1

포인터 질문이 있습니다

0

322

1

20:35 에서 구조체 크기에 대한 질문입니다!

0

584

1

iterator 삭제관련

0

406

1

함수 호출을 디스어셈블러로 분석하다가 궁금점이 생겼습니다!

0

310

1

15 분 45초 대 질문

0

308

0

스택 프레임 질문합니다!

2

306

1

오른값 참조 in 게임

0

384

0

동적할당 질문이 있습니다

0

449

1

안녕하세요 메모리에 대해 질문드립니다.

0

304

1

함수객체 의 매개변수

0

358

1

복사생성자

0

434

1

main이나 endl 부분이 주황색으로 표시된건 어떻게 하나요

0

419

1

포인터 실습 강의를 보고 궁금한게 있습니다.

0

353

1

스택 오버플로우

2

790

1