C++ 공부 18일 차
다형성
- 상위 유형의 변수가 하위 유형 객체를 참조할 수 있음을 의미합니다.
- 상위 유형(subtype) : 기본 클래스에 의해 정의된 유형
- 하위 유형(supertype) : 파생 클래스에 의해 정의된 유형
- ex) GeometricObject라는 기본 클래스와 이 클래스에서 파생된 Circle, Ractangle 2개의 파생 클래스가 있을 때,
GeometricObject가 상위 유형, Circle, Ractangle이 하위 유형에 속한다.
- 기본 클래스 유형(상위 유형)의 매개변수에 파생클래스(하위 유형)의 인스턴스를 항상 전달할 수 있다.
하지만 그 반대는 불가능하다.
ex) 모든 Circle은 GeometricObject에 속하지만, GeometricObject의 일부만 Circle에 속하기 때문.
가상 함수와 동적 결합
- 가상 함수는 시스템이 객체의 실제 유형에 기초하여 실행 시 어느 함수를 호출할지 결정할 수 있도록 한다.
- 가상 함수 사용은 [virtual] 키워드를 사용하여 함수를 선언하면 됩니다.
ex) virtual string toString();
- 위의 virtual 키워드로 선언된 함수를 파생 클래스에서 재정의 할 수 있으며, 컴파일러는 실행 시에 어떤 함수 구현을 사용할 것인지를 동적으로 결정합니다. 이렇게 재정의 하는 것을 함수 오버라이딩이라 하고, 동적으로 결정하는 것을 동적 결합이라 합니다.
- 동적 결합의 조건은
1. 함수는 기본 클래스에서 virtual로 정의되어야 한다.
2. 객체를 참조하는 변수는 가상 함수에서 참조에 의해 전달되거나 포인터로서 전달되어야 한다.
- 만약 전달할 때 참조나 포인터로 전달하지 않고 값에 의해 전달된다면, 전달된 객체의 함수가 작동하는게 아닌, 기본 클래스의 함수가 작동하게 됩니다.
ex) virtual string toString() 함수를 사용할 때
참조 or 포인터 : Geometric, Circle, Rectangle
값 : Geometric, Geometric, Geometric (Geometric이 기본 클래스, Circle, Rectangle이 파생 클래스)
- 기본 클래스에서 virtual로 정의된 경우, 그 기본 클래스의 모든 파생 클래스에서 자동으로 virtual이 된다.
- 가상 함수는 기본적으로 실행 시에 함수 구현을 동적으로 결합하며 시간과 시스템 자원을 기본 함수를 쓸 때보다 더 많이 사용하게되기 때문에 함수를 파생 클래스에서 재정의하지 않는다면 가상 함수를 선언하지 않는 것이 더 효과적이다.
protected 키워드
- protected 키워드는 public, private와 비슷한 키워드로, 클래스에서 사용하는 키워드입니다.
- public은 객체 선언만 하면 접근이 가능하고, private는 객체를 선언해도 접근이 불가능하지만,
protected는 파생 클래스에서 접근이 가능합니다.
- public, private, protected 키워드는 클래스와 클래스 멤버에 접근할 수 있는지를 명시하므로,
가시성(visibility) or 접근성(accessibility) 키워드라고 합니다. 기본적으로 private, protected, public 순으로 가시성이 증가합니다.
순수 가상 함수와 추상 클래스
- 순수 가상 함수(pure virtual function)은 추상 함수(abstract function)라고 하기도 하며, 해당 함수를 포함하는 클래스는 추상 클래스가 됩니다.
- 순수 가상 함수는 위 가상 함수의 예시 virtual string toString();에서 = 0를 추가하면 됩니다.
ex) virtual string toString() = 0;
- 순수 가상 함수는 기본 클래스에서 함수의 몸체나 구현 내용이 없고, 파생 클래스에서 재정의해서 사용합니다.
- 해당 함수를 포함하는 추상 클래스는 객체를 생성하는 데 사용될 수 없지만, 제네릭 프로그래밍이 가능하도록 함수에서 매개변수에 대한 데이터 유형으로 추상 클래스를 사용할 수 있습니다.
- 기본 클래스 유형의 객체를 파생 클래스 유형으로 형변환하기 위해서 static_cast 와 dynamic_cast 연산자를 사용할 수 있으며, static_cast는 컴파일 시에, dynamic_cast는 실행 유형 확인을 위해 실행 시에 수행됩니다. dynamic_cast의 경우 다형성 유형(즉, 가상 함수를 포함하는 유형)에 대해서만 수행될 수 있습니다.