Part3) CH9. 추상화와 C++의 OOP

songtofu·2022년 12월 14일
0

전문가를 위한 C

목록 보기
9/10

9.1 추상화

  • OOP에서 추상화? 추상 자료형을 다루는 것
  • 추상 클래스? 객체로 만들 수 없는 특별한 클래스
  • 필요성? 코드의 여러 부분 간에 강한 의존성이 생기지 않기 때문 ex. 인간, 사과, 과일
  • 정확한 값이 있는 것 = 구상 자료형
  • 추상화는 의존성이 최소인 객체 모델을 설계하는 가장 좋은 방식임.
  • 문제를 해결하는 데 필요한 수준보다 더 추상적인 추상 자료형을 찾아낼 수 있음. = 과도한 추상화. 문제를 일으킬 수 있음 반드시 피해야함(뭔 문제..?)
  • 추상화 원칙(위키백과 페이지 인용): 프로그램의 중요한 각 기능은 소스 코드의 오직 한 부분에서만 구현되어야 한다. 비슷한 기능을 별개의 코드에서 수행할 때는 일반적으로 다양한 부분을 추상화해 하나로 결합하는 편이 좋다.
  • 다형성은 자식 클래스가 부모 행위를 오버라이딩할 수 있게 함. (적절한 값을 반환하도록 함.)
  • 가상 함수는 정의가 아예 없을 수도 있음. 이러한 가상함수는 소유자 클래스를 추상화함.
  • 속성과 기본 정의를 갖지 않는 가상 함수만을 포함하는 클래스 = 인터페이스
  • 인터페이스는 기능은 노출하지만 구현은 노출하지 않음. 소프트웨어 프로젝트에서 다양한 컴포넌트 사이의 의존성을 만드는데 사용(?)
  • 추상 자료형으로 객체르 ㄹ생성하지 않으려면 클래스의 공용 인터페이스에서 할당자 함수를 제거. 오직 자식 클래스만이 부모의 속성 구조체로부터 객체를 생성할 수 있다.
  • C에서 추상 클래스를 갖기 위해 필요한 사항
    1. 추상화 수준에서 기본 정의를 갖도록 한 가상 함수 포인터를 NULL로 만들어야함.
    1. 매우 높은 추상화 수준에서는 모든 함수 포인터가 NULL인 인터페이스를 갖음.
    2. 추상 자료형으로부터 외부 코드가 객체를 생성하지 못하게 하려면 공용 인터 페이스에서 할당자 함수를 제거해야 함.

    9.2 C++의 객체지향 구성물

  • 지금부터 언급할 C++은 C++컴파일러 중 하나인 g++에 대한 구현을 가리킴.

    9.2.1 캡슐화

  • C 함수에서 생성된 어셈블리 코드는 매우 높은 정확도로 C++ 함수에 대해 생성된 어셈블리 코드와 거의 같다. 이를 토대로 C++ 컴파일러는 캡슐화를 구현하기 위해 암묵적 캡슐화로 소개했던 C의 접근법과 유사한 방식을 사용했다고 결론

9.2.2 상속

  • C++에서 자식 클래스의 포인터는 부모 클래스의 포인터로 할당할 수 O
  • 자식 클래스는 부모 클래스의 비공개 정의에 접근.
    -> C++가 상속을 구현하는 첫 번째 접근법을 사용하고 있음.
    But, C++은 첫 번째 접근법에서 지원하지 못하는 다중 상속을 지원.
  • 행위 함수와 속성은 클래스에서 별개로 취급. C++에서는 클래스 내의 위치와 상관없이 속성은 언제나 특정 객체에 대해 같은 메모리 블록 안에서 수집. 함수는 속성과 언제나 독립적으로 존재(6장 암묵적 캡슐화)
c_t c_obj;
a_t* a_ptr = (a_ptr*)&c_obj;
b_t* b_ptr = (b_ptr*)(&c_obj + sizeof(a_t));
c_t* c_ptr = &c_obj;

9.2.3 다형성

  • 비가상 함수에 대한 호출은 단순한 함수 호출, 가상 함수는 부모 또는 자식 생성자에 의해 설정된 적절한 함수로 호출을 다시 전달.
  • C++에서 virtual 키워드로 행위 함수를 가상으로 선언할 때 C++은 함수 포인터 배열을 만든다.
  • C++에서 포인터를 두는 좋은 방식: 가상 테이블 vtable이라는 배열을 사용.
  • 가상 테이블은 기초 클래스에 대한 생성자를 호출할 때 처음 추가, 그 뒤에 자식 클래스의 생성자의 일부가 된다.
  • 가상 테이블은 생성자에서만 추가, 부모 및 자식 클래스 모두 생성자에서 다형적 메서드를 호출하지 않아야함. 포인터가 업데이트되지 않았을 수 있고, 틀린 정의를 가리킬 수도 있기 때문.

9.2.4 추상 클래스

class Eatable {
public:
	virtual Taste GetTaste() = 0;
}
  • 위의 코드는 순수 가상 함수를 정의한 것.
  • 순수 가상 함수에 대한 포인터의 초깃값은 null. 일반적인 가상 함수의 포인터는 생성이 진행되는 동안 기본 정의를 가리켜야함.
  • C++컴파일러는 추상 자료형을 알고 있음.-> 추상 자료형 객체 생성? 컴파일 오류!
profile
읽으면 머리에 안들어와서 직접 쓰는 중. 잘못된 부분 지적 대환영

0개의 댓글