▶ 객체지향 4대 요소
- 캡슐화
ㄴ 데이터 오염 방지, 객체의 속성을 보호하기 위한 키워드.
- 상속
ㄴ 구체화, 하위로 내려 갈수록 구체화 되는 것.
- 다형성
ㄴ 여러 형태 변화, 하나의 객체가 여러 형태로 변화 하는 것.
- 추상화
ㄴ 설계, 공통적인 부분과 특정 특성을 분리 및 추출하여 재조합 및 재구성하는 것을 의미.
▶ 객체지향 5대 설계 원칙 (SOLID)
- 단일 책임 원칙 (SRP, SingleResponsibilityPrinciple)
ㄴ 결합도는 낮추고 응집도를 높여라.
ㄴ 상속 / 오버라이딩을 사용하면 응집도가 높아진다.
- 개방-폐쇄 원칙 (OCP, OpenClosedPrinciple)
ㄴ 자신의 확장에는 열려 있고, 주변의 변화에 대해서는 닫혀 있어야 한다.
- 리스코프 치환 원칙 (LSP, LiskovSubstitutionPrinciple)
ㄴ 하위 타입은 언제나 자신의 기반인 상위 타입으로 교체가 가능해야 한다.
인터페이스 분리 원칙 (ISP, InterfaceSegregationPrinciple)
ㄴ 클라이언트는 자신이 사용하지 않는 함수 / 메서드에 의존 관계를 맺으면 안된다.
의존관계 역전 원칙 (DIP, DependancyInversionPrinciple)
ㄴ 자신보다 변하기 쉬운 것에 의존하면 안된다.
▶ 순수가상 함수
- 함수의 구현부가 없고, 기본적으로 선언부가 =0, NULL, PURE, abstract 로 끝나는 가상함수.
- 부모 클래스에서 순수 가상함수를 선언하면 자식 클래스에서 반드시 재정의한 함수를 멤버로 가져와야 한다.
▶추상 클래스
- 순수 가상 함수가 N개 이상 있는 클래스를 의미한다.
▷ 특징
1. 객체를 생성 할 수 없다.
2. 포인터 변수는 만들 수 있다.
3. 추상클래스로 지정한 객체는 인스턴스를 만들 수 없다.
4. 추상 클래스의 자식 클래스를 통해 인스턴스를 생성 할 수 있다.
5. C++언어가 개정되면서 추가된 abstract 키워드를 통해 명시하는 것 가능
6. 더 나아가 C++11 이상의 버전부터는 멤버 변수 또는 멤버 함수가 포함된 여부와 상관없이 순수 가상함수를 1개 이상 가지고 있다면 이 클래스는 추상 클래스로 승격이 된다.
▶ 인터페이스
- OCP
ㄴ 자신의 확장에는 열려 있고, 주변 변화에 대해서는 닫혀 있어야 한다.
- 순수 가상함수로만 이루어진 클래스를 인터페이스라고 한다.
- 인터페이스 개념은 하위 클래스에서 반드시 정의해야 할 함수를 정해주는 클래스라고 할 수 있다.
- C / C++ 언어에서는 공식적으로 인터페이스라는 기능을 지원하지 않는다.
ㆍ 구조도
Interface (극추상화) -> (상속) -> abstract 클래스 (기본 기능 구현) -> (상속) -> 기본 클래스 (순수 가상함수 재정의)
▷ 인터페이스 특징
- 멤버 변수 및 함수를 포함 할 수 없다. (정적 함수 포함)
- 속성을 정의하는 한정자(const) 사용 금지.
- 기본 클래스를 상속 받을 수 없다.
- 순수 가상 함수만 포함 시켜야 한다.
- 생성자 / 소멸자 / 연산자를 포함 할 수 없다.
- 상속이 전제되기 때문에 public 속성을 가지고 있어야 한다.
▷ 장점
- 다중 상속에서의 안정성이 좋다.
- C++ 언어에서 많이 발생하는 다중 상속 / 중첩화 현상을 방지 할 수 있다.
- 인터페이스를 이용하면 중첩화 현상 없이 다중 상속을 가능하게 한다.
▷ 단점
- 추상화를 기본으로 삼아 구현하기 때문에 가독성이 떨어진다.
- C++ 언어에서는 키워드를 사용 할 수 없기 때문에 멤버 변수 선언 등에 주의를 요해야 한다.
- 강제성이 없고 프로그래머에 의한 실수가 발생할 여지가 아주 다분하다.
★ 가상 소멸자
ㄴ 상속 관계에서 사용하면 자식 클래스의 소멸자를 호출한다는 점에서 잠재적인 오류를 예방하지만 상속 관계가 아닐 경우 성능 저하가 발생하기 때문에 주의해야 한다.
▶ 가상함수 테이블
C++의 다형성을 구현하는 기본 매커니즘.
가상 함수 호출을 동적으로 바인딩하는데 사용.
클래스에서 가상 함수가 하나 이상 있으면, 컴파일러는 해당 클래스를 위해 가상 함수 테이블을 생성.
이 테이블은 각각의 가상 함수에 대한 포인터를 저장.
컴파일러는 클래스의 각 객체에 대해 vptr(virtual table pointer)라는 포인터를 추가.
이 vptr은 해당 객체의 클래스 타입에 따른 가상 함수 테이블을 가리킨다.
- 상속받은 클래스에서 깁곤 클래스의 가상 함수를 오버라이딩하면, 컴파일러는 상속받은 클래스에 대한 새로운 VTable을 생성하고, 이 VTable에서 오버라이드 된 함수들의 주소는 새로운 함수들로 업데이트 되지만, 나머지 함수들은 원래 기본 클래스의 버전을 계속 참조.
런타임 시 객체가 어떤 타입인지 확인 할 필요 없이, vptr을 통해 바로 해당 객체가 사용 할 수 있는 올바른 함수 버전으로 접근 가능.
이 방식이 C++에서 다형성과 동적 바인딩이 가능한 방법.
이런 방식 때문에 추가적인 오버헤드(객체 당 하나씩 추가되는 vptr과 각 클래스마다 생성되는 VTable 등)가 발생하므로, 성능 최적화가 중요한 경우 반드시 필요한 곳에서만 사용해야 함.
'WinAPI' 카테고리의 다른 글
슈팅게임, 탄환관리 (0) | 2023.06.20 |
---|---|
KeyManager (0) | 2023.06.16 |
Random, DesignPattern:Singleton (0) | 2023.06.14 |
매크로 상수/함수, 한정자 (0) | 2023.06.13 |
PCH, Parsing, Character Set (0) | 2023.06.12 |