승쨩개발공부
[C++] 가상 함수(virtual), 가상 소멸자, 순수 가상 함수 본문
virtual(가상)
실세계 에서 가상
-> 존재하지 않는 것을 존재하는 것처럼 느끼게 하는 것.
프로그래밍 에서 가상
-> 존재하는 것을 존재하지 않는 것처럼 느끼게 하는 것.
반환 타입 앞에 virtual 키워드를 명시하면 가상 함수가 된다.
-> 존재하는 함수를 존재하지 않는 것처럼 만든다.
가상 함수를 통해 함수를 호출하면 함수를 없는 것처럼 만드는 것이기 때문에 호출해야할 함수가 사라진다.
이 경우, 같은 함수를 다시 만들어서 호출한다.
Func함수는 virtual 키워드로 인해 가상 함수가 되었다.
-> 호출할 시점에 없는 취급을 해라.
-> 단, 없는 취급했더니 진짜로 호출할 함수가 없을 경우에는 다시 만들어서 호출한다.
부모 클래스의 가상 함수를 자식 클래스가 오버라이딩 할 경우
자식 클래스의 함수 또한 가상 함수가 된다
(virtual 키워드 또한 상속이 된다)
부모의 가상 함수를 자식 클래스가 오버라이딩 할 경우
vitual 키워드로 인한 혼란스러움을 방지하기 위해
자식 클래스에서 오버라이딩한 함수에도 virtual 키워드를 명시해주는 것이 좋다.
가상 함수 판단
1. 가상 함수가 아닐 경우 객체 타입 기준으로 함수를 호출한다.
2. 가상 함수일 경우 객체 타입이 아닌 실 객체의 함수를 호출한다.
가상 함수 테이블
virtual 키워드가 단 하나 이상이라도 존재한다면
컴파일러는 가상 함수 테이블을 만든다.
가상 함수 테이블에는 virtual 함수들의 주소가 저장된다.
이후, 함수를 호출할 떄 해당 함수가 vitual 함수일 경우
객체 타입 기준으로 호출하지 않고 가상 함수 테이블을 확인하여 호출한다.
상속 관계에서의 생성자, 소멸자 호출 순서
객체 생성 -> 메모리 할당 -> 부모 생성자 호출 -> 자식 생성자 호출
-> 부모 생성자 호출 -> 메모리 반환 -> 객체 소멸
다음과 같이 부모와 자식 클래스에 생성자와 소멸자를 추가하고 디버깅을 하게 된다면?
위와같이 CPlayer의 소멸자는 호출이 되지 않는다.
-> 이유는 소멸 시키는 대상이 pObj이기 때문이다.
-> pObj를 통해 알 수 있는 것은 Heap영역의 시작 주소만 알 수 있다.
-> 시작 주소부터 몇 바이트를 소멸할 것인지는 타입을 통해 확인한다.
-> 타입이 CObj*이기 댸문에 CObj의 소멸자만 호출하고 끝이난다.
-> CPlayer의 소멸자를 호출하기 위해서는 가상 함수 포인터를 사용하면된다.
-> CPlayer의 소멸자가 정상적으로 호출된다.
순수 가상 함수
함수의 정의부가 없는 함수
-> '=0' 으로 마무리 한다.
-> 단, 순수 가상 함수는 객체를 만들 수 없다.
-> 객체 포인터로는 사용이 가능하다.
상속 관계에서 다형성을 만들 경우 순수 가상 함수를 사용한다
-> 자식 클래스에서 부모의 순수 가상 함수를 오버라이딩(재정의) 하지 않을 경우
-> 자식 또한 추상 클래스가 되기 때문에 실수를 방지할 수 있다.
추상 클래스?
-> 순수 가상 함수를 단 하나라도 가지고 있는 클래스를 추상 클래스라 한다.
-> 추상 클래스는 객체로 만들 수 없다.
-> 단, 객체 포인터로는 사용이 가능하다.
vitual 정리
-> 존재하는 함수를 존재하지 않는 것처럼 만든다.
-> 호출할 함수가 없을 경우 다시 만들어서 호출한다.
단, 오버라이딩 된 함수를 virual로 만들 경우 자식 함수 또한 vitual을 자동 상속 받는다.
'C++' 카테고리의 다른 글
[C++] 바인딩 (0) | 2021.12.06 |
---|---|
[C++] 캐스팅 (static_cast, dynamic_cast, const_cast, reinterpret_cast) (0) | 2021.12.06 |
[C++] 오버라이딩 (0) | 2021.12.03 |
[C++] 객체 포인터 (0) | 2021.12.03 |
[C++] 상속 (0) | 2021.12.03 |