핵심 기념
1. 상속: 객체 단위 코드를 재사용하는 방법.
2. 재사용: 기능적 확장이나 개선을 의미
3. 재정의(오버라이딩): 기존의 선언 및 정의된 코드를 유지하면서도 새롭게 바꾸는 방법
4. 메서드 재정의: 어떤 클래스에 있는 메서드를 자유롭게 재정의해서 사용하는 방법
학습 목표
1. 상속의 개념
2. 상속을 통한 메서드의 재정의 방법을 직접 작성
3. 상속의 경우 생성자와 소멸자가 어떻게 사용되는지를 이해
1. 상속:
- 상속: 객체 단위 코드를 재사용하는 방법.
- 재사용: 기능적 확장이나 개선을 의미
A. 기본 문법
i. class 파생클래스 이름 : 접근제어지시자 부모 클래스이름
ii. is-a / has-a 관계
iii. 특징
u 파생 클래스의 인스턴스가 생성될 때 기본 클래스의 생성자도 호출
u 파생 클래스는 기본 클래스의 멤버에 접근할 수 있습니다. 단, private 접근 제어 지시자로 선언된 클래스 멤버에는 접근할 수 없습니다.
u 사용자 코드에서는 파생 클래스의 인스턴스를 통해 기본 클래스 메서드를 호출
iv. 부모 클래스에서 protected로 선언된 멤버함수를 자식 인스턴스로 호출이 가능한가?
l 불가능함
v. 부모클래스와 파생클래스의 호출과 실행 순서: Stack
u 파생 클래스 선언
u 상위클래스 생성자 호출
u 상위 클래스 생성자 실행 및 반환
u 파생 클래스 생성자 실행
u 파생 클래스 생성자 반환
vi. 파생클래스가 접근가능한 부모 클래스의 멤버 범위
l public / protected
B. 2.5 식별자 검색 순서
i. 클래스 메서드
1. 현재 블록 범위
2. 현재 블록 범위를 포함하고 있는 상위 블록 범위(최대 적용 범위: 함수 몸체까지)
3. 클래스의 멤버
4. 부모 클래스의 멤버
5. 가장 최근에 선언된 전역 변수나 함수
6. 호출자 코드가 속한 네임스페이스의 상위 네임스페이스
7. Using 선언된 네임스페이스 혹은 전역 네임스페이스
ii. 멤버함수를 선언할 때
1. 오버라이딩 된 함수를 선언할 경우 명시적으로 선언하지 않을 경우
2. 식별자 검색 순서의 의해 클래스의 멤버로 받는다.
3. 명시적으로 ::를 표현해주어 부모클래스의 멤버를 호출한다.
2. 메서드 재정의(메서드 오버라이딩)
n 메서드를 재정의하면 기존의 것이 ‘무시’가 된다.
A. 기본 문법 및 특징
- 의문?: 오버로딩: 매개변수가 다르지만 함수명이 같은 함수
n 파생클래스에서 오버로딩으로 함수를 선언할 경우
n 이는 새로운 함수인가 오버로딩인가 오버라이딩인가
- 재정이의 이유: 기존 메서드와 새 메서드를 한데 묶어 작동하게 하려는 의도
- Protected 접근 제어 지시자로 선언된 클래스를 상속하면
n 상위 클래스 메서드를 명시적으로 호출이 불가능함 public 만 가능
- 멤버 변수명을 부모클래스와 같게 선언 하지마라
n 문법적으로 가능은 하나 바람직하지 않음
B. 참조 형식과 실 형식
u 파생 형식을 기본 형식으로 참조하는 것은 매우 자연스러운 일이다.
- 부모 클래스& 인스턴스 = 파생 인스턴스;
n 위 경우 참조 형태로 선언된 인스턴스는 부모 클래스 형식으로 선언되었으므로 부모 멤버함수를 호출하게 된다.
n 파생 클래스에 오버라이딩된 함수가 있을 경우, 함수를 호출하게 되면 부모클래스의 함수를 호출함
- 부모 클래스 *인스턴스 = new 파생 클래스;
n 부모클래스의 포인터 변수에 파생 클래스의 공간을 할당함
n 위 경우도 부모 클래스의 멤버 함수가 호출됨
n 하지만 메모리 누수 오류가 존재함
u delete 연산을 실행하더라도 파생 클래스의 소멸자는 호출되지 않음
u I think 호출된 건 부모 클래스이므로 소멸자도 부모클래스 소멸자가 호출되고 파생 클래스의 메모리를 할당했기 때문에 소멸자가 제대로 역할을 하지 못함
3. 상속에서 생성자와 소멸자
- 생성자
n 상속을 통해 클래스는 비중이 커진다.
n 파생 인스턴스를 선언하면 호출은 먼저 이루어 지지만 부모 클래스의 생성자가 먼저 실행되고 파생 클래스의 생성자가 실행된다.
n 즉, 상속에서 생성자는 Stack의 개념으로 접근한다.
- 소멸자
n 소멸자는 호출과 동시에 실행한다.
n 파생 클래스의 소멸자가 호출되고 즉시 실행되며, 이후 부모클래스의 소멸자가 호출되고 실행된다.
- 파생 클래스에서 상위 클래스 생성자는 하나만 “선택”할 수 있다.
n 별도로 생성자를 선택하지 않으면 디폴트 생성자가 선택된다.
- 파생 클래스에서 부모 클래스의 소멸자에 접근할 경우 심각한 오류를 발생한다.
n 소멸자는 파생 클래스가 먼저 호출되고 실행되므로 소멸자를 실행할 때 부모클래스의 메모리 해제를 진행하고
n 이후 부모 클래스의 소멸자가 호출되어 메모리 해제를 할 경우 없는 메모리를 해제하려고 하여 오류를 발생 시킨다.
- 알아 두면 좋을 상식
è 파생 클래스는 부모 클래스의 멤버 변수에 직접 쓰기 연산하지 않는 것이 정답이다.
è 파생클래스 생성자에서 부모 클래스 멤버 변수를 초기화하지 않는다.
è 생성자와 소멸자는 객체 자신의 초기화 및 해제만 생각한다.
A. 생성자 선택
u 파생 클래스의 생성자는 자신이 호출된 후 부모 클래스의 생성자 중 어떤 것이 호출 될 것인지 선택이 가능
u 생성자 초기화 목록에 기술한다.
i. 생성자 상속: 다중 정의된 상위 클래스의 생성자들을 그대로 가져오는 문법
l C++11에서 등장함
l Visual studio 현재 지원함
l using 부모클래스::부모클래스;
연습문제
1. 파생 클래스에서 일반메서드를 재정의 했다고 가정. 만일, 파생 형식 인스턴스를 기본 형식에 대한 포인터로 포인팅하고 호출한다면 기본형식과 파생형식중 어느 클래스의 메서드가 호출될까
A) 기본 형식
2. A는 B의 B는 C의 기본 클래스일 때 C 클래스의 인스턴스를 선언한다고 가정하면 가장 먼저 ‘실행’되는 생성자는 어느 클래스의 생성자인가?
A) A 클래스의 생성자
'C++ > 이것이 C++이다.' 카테고리의 다른 글
Ch10. 예외 처리 (0) | 2021.01.15 |
---|---|
Ch7. 상속 심화 (0) | 2021.01.15 |
Ch5. 연산자 다중정의 (0) | 2021.01.15 |
Ch4. 복사 생성자와 임시 객체 (0) | 2021.01.15 |
Ch3. 클래스 (0) | 2021.01.15 |
최근댓글