티스토리 뷰


상속

 : 클래스와 클래스간에 계층구조를 형성할 수 있는 기능이다. 

 - 클래스는 다른 클래스를 상속받아서, 상속받은 클래스를 확장한 클래스로 만들어서 사용할 수 있다.

 - 상속을 받게되면 부모클래스의 멤버변수, 멤버함수들을 물려받아서 사용할 수 있다.

 - 단, 부모에 private 으로 지정되어있는 변수나 함수는 사용할 수 없다.


다중상속

 : 여러 부모를 상속받을 수 있다.



# 위와같이 부모, 자식 클래스를 생성해주었다.






# 자식클래스의 객체를 생성시에 부모-자식 간 생성자와 소멸자의 실행순서를 알아보자

부모 생성자 → 자식 생성자 → 자식 소멸자 → 부모 소멸자 순서로 진행된다.


# 상속구조에서의 생성, 소멸자 호출 순서
생성자 : 부모 -> 자식
소멸자 : 자식 -> 부모





#

public : 어디에서든 접근 가능하다.

protected : 상속관계의 클래스에서 접근 가능하다. 외부에서는 접근 불가능하다.

private : 외부에서 접근이 불가능하다.


#)_ 참고

friend 처리를 해주면 지정한 클래스에서 이 클래스의 private에 접근할 수 있다.






다형성

 : 상속관계에 있는 부모클래스와 자식클래스는 서로 형변환이 가능하다.

 - 자식 → 부모 : 업캐스팅

 - 부모 → 자식 : 다운캐스팅

 - 다형성은 상속관계에 있는 클래스간에 서로 형변환이 가능한 성질을 말한다.

 - 다형성을 이용하여 자식 클래스로 생성한 객체를 부모타입으로 형변환 해둘 경우

   객체가 메모리 해제시에 자식의 소멸자가 호출이 안될수도 있고, 

   자식에만 있는 함수를 호출하기 위해서는 형변환을 해야 한다.

 - 다운 캐스팅은 아주 많은 위험 요소를 가지고 있다. 

   예를 들어 CChild와 CChild1은 메모리 구조가 다르다. 

   그런데 CChild나 CChild1은 둘다 CParent클래스를 상속받고 있다. 

   같은 부모이기 때문에 같은 부모타입의 포인터에 각자 객체를 생성해서 담아둘 수 있다. 

   그런데 부모포인터 타입에 저장된 CChild 객체를 CChild1 객체로 형변환 할 수도 있다. 이런 경우 문제가 된다.


이번에는 다형성을 이용하여 부모타입의 포인터 변수에 자식 타입을 동적할당 해보자.

# 위처럼 할당을 해준다고 하더라도 근본적으로 pChild 변수는 CParent 의 포인터 타입이다.

그렇기 때문에 자식의 변수나 함수에는 바로 접근할 수 없다. 
그래서 CChild 클래스의 소멸자에 접근이 불가능하게 된다. 

이러한 문제를 해결하기 위해서 C++에서는 가상함수를 제공해준다.





가상함수
 - 가상함수는 부모에 선언된 함수를 자식에 재정의하여 재정의된 함수를 호출해 줄 수 있도록 만들어준 기능
 - CChild 클래스를 이용하여 객체를 할당해 주었다.
   CParent 클래스의 소멸자에 virtual을 붙여주어 소멸자를 가상 소멸자로 만들어보자

# 가상함수가 클래스에 존재하면 해당 클래스를 이용하여 생성하는 객체들은 가상함수테이블 이라는 것을 가지게 된다. 

가상함수 테이블에는 함수의 메모리 주소가 저장된다. 
위의 경우 소멸자가 가상함수이므로 부모가 아닌 자식소멸자의 메모리 주소가 
가상함수 테이블에 들어가 있게 되고 소멸자를 호출시 가상함수이므로 먼저 가상함수 테이블을 참조하게 되고 
가상함수테이블에 자식 소멸자의 주소가 들어가 있으므로 자식의 소멸자를 먼저 호출해주게 된다.

가상함수를 사용하는 경우

 - 자식클래스를 이용하여 생성한 객체들을 부모 포인터 타입으로 하나로 모아서 관리할때

 - 자식 클래스들마다 개별적인 기능을 만들어줘야 할 경우 부모의 함수를 가상함수로 만들고 

 - 자식에 재정의하여 개별적인 기능을 구현할 때 사용할 수 있다.






순수가상함수

 - 가상함수 뒤에 = 0; 을 붙여주면 순수가상함수가 된다. 

 - 순수가상함수를 가지고 있는 클래스를 추상클래스라고 한다. 추상클래스는 객체 생성이 불가능하다. 

 - 오로지 인터페이스 용으로만 사용이 가능하다.

 - 순수가상함수는 구현부분을 안해도 된다. 그렇기 때문에 일반 가상함수보다는 조금은 더 빠를 수 있다.

 - 순수가상함수는 반드시 자식에서 재정의 해야된다(구현부분을 하지 않기때문).


순수가상함수를 사용할 때

 : 부모타입 클래스에서 특정 함수를 구현하지 않고 자식부분에서 재정의하고자 할 때 사용할 수 있다.


# 순수가상함수를 자식 클래스에 재정의해주지 않으면 오류가난다.






예를들어 설명해보면

 - CParent1의 Update 함수를 99번지 라고 한다.

 - CChild1의 Update 함수를 100번지
 - CChild2의 Update 함수를 200번지
 - CChildChild1의 Update 함수를 300번지라고 가정한다(CChild1의 자식클래스).
 - CChild1을 할당하면 가상함수 테이블에 Update 함수의 주소는 100번지가 저장된다.
 - CChild2를 할당하면 가상함수 테이블에 Update 함수의 주소는 200번지가 저장된다.
 - CChildChild1을 할당하면 가상함수 테이블에 Update 함수의 주소는 300번지가 저장된다.
 - 호출시 가상함수라서 가상함수테이블을 참조하게 되고, 가상함수 테이블에는 Update 함수의 주소가 
생성된 객체에 따라서 다르게 저장되어 있으므로 각 함수를 호출해주게 된다.
 - 단, 자식에서 Update 함수를 재정의(override) 하지 않았다면 부모의 함수 주소로 저장된다.
















'BASIC LANGUAGE > C++' 카테고리의 다른 글

*) DLL 추출 및 사용  (0) 2018.05.16
*) 상속, 다형성, 가상함수  (0) 2018.03.12
*) C++를 이용한 TCP 소켓통신 구현  (12) 2018.02.27
댓글
댓글쓰기 폼
공지사항
Total
290,627
Today
19
Yesterday
32
링크
TAG
more
«   2022/08   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
글 보관함