반응형

소스 코드 353

[C++] 37. 하향 캐스팅(dynamic_cast)

이번에는 기반 형식 포인터 변수로 참조하고 있는 형식을 프로그램 동작 시에 파생 형식으로 형 변환하는 하향 캐스팅을 알아보기로 해요. 다형성은 캡슐화와 상속을 보다 효과적이고 현실 세계에 근접하게 표현할 수 있게 해주는 특징입니다. 하지만 기반 클래스 형식 포인터 변수로 파생 개체를 관리하는 것은 치명적인 단점이 있습니다. 만약 기반 클래스 형식에서는 약속할 필요가 없는 메서드가 파생 클래스 형식에 있을 때 해당 메서드의 접근 수준을 public으로 제공해도 접근하지 못합니다. 이러한 약점을 보완하기 위해 많은 OOP언어에서는 런 타임에 파생 개체 형식으로 형 변환(캐스팅)하는 방법을 제공하고 있으며 이를 하향 캐스팅이라 합니다. C++언어에서는 dynamic_cast를 통해 하향 캐스팅을 제공하고 있습..

[C++] 36. 다중 상속

이번에는 여러 개의 기반 형식에서 파생하는 형식을 정의하는 다중 상속을 살펴볼게요. C++언어에서는 기반 형식을 여러 개를 정의하는 다중 상속을 지원합니다. 많은 이들은 다중 상속을 사용할 때 주의하라고 권하거나 아예 다중 상속을 사용하지 말 것을 권합니다. 실제 Java나 C#에서는 여러 개의 기반 클래스에서 파생하는 형식을 정의하는 문법을 제공하지 않습니다. C++보다 나중에 만들어진 이들 언어에서는 C++언어의 다중 상속 문법의 위험을 알고 난 이후에 만들어져서 이러한 문법을 제외하고 있습니다. 그렇지만 Java나 C#에서도 여러 개의 인터페이스를 기반으로 파생한 형식을 정의하는 문법은 제공하고 있습니다. 여기에서는 C++언어에서 제공하는 다중 상속이 어떠한 위험을 갖고 있는지 살펴보고 Java나 ..

[C++] 33. 메서드의 다형성 (virtual 키워드와 가상 메서드)

이번에는 메서드의 다형성을 살펴볼게요. 형식의 다형성은 기반 형식 포인터 변수로 파생 형식 개체를 설정하거나 기반 형식 참조 변수로 파생 형식 개체를 설정할 수 있는 특징이죠. 그런데 형식의 다형성만 제공한다면 기반 형식 변수로 멤버 메서드를 호출하면 실제 개체 형식에 관계없이 기반 형식에 정의한 메서드가 동작합니다. 메서드의 다형성은 기반 형식 변수로 멤버 메서드를 호출하였을 때 실제 개체 형식에 정의한 메서드가 동작할 수 있는 OOP언어의 특징입니다.예를 들어 음악가 형식을 기반으로 파생한 형식으로 피아니스트와 드러머가 있다고 가정할게요. 그리고 음악가에는 “연주하다.”와 “인사하다.” 기능을 제공할거예요. “인사하다.” 기능은 파생 형식에 관계없이 같은 동작을 수행하지만 “연주하다.” 기능은 파생 ..

[C++] 30. 무효화

기반 클래스에서 정의한 멤버 메서드와 같은 이름으로 파생 형식에서 정의하면 어떻게 동작할까요? 파생 클래스에서 기반 클래스에 정의한 이름과 같은 이름으로 메서드를 만들면 기반 클래스에 정의한 메서드를 무효화합니다. 예를 들어 일반 프로그래머가 있고 EH 프로그래머가 있는데 대부분의 행위에 있어 EH 프로그래머는 일반 프로그래머와 같게 일을 한다고 가정합시다. 하지만 일반 프로그래머가 프로그래밍을 할 때 "생각하면서 코딩을 한다."와 같이 하는데 EH 프로그래머가 프로그래밍을 할 때는 "생각한 것을 문서화 하고 이를 보면서 코딩을 한다."고 해 볼게요. 이 때 일반 프로그래머의 프로그래밍이라는 메서드를 무효화합니다. //무효화#include #include using namespace std;class P..

[C++] 29. 접근 지정자 protected

이번에는 접근 지정자 protected에 관해 알아보기로 해요. 캡슐화에서 접근 지정자를 사용하여 멤버의 가시성을 설정할 수 있다는 것을 다뤘었죠. private으로 접근 지정한 것은 형식 내부에서 사용할 수 있고 public으로 지정하면 모든 곳에서 접근할 수 있다는 것은 이미 소개하였습니다. 파생 클래스를 정의하면 기반 형식의 멤버를 상속받는다고 하였는데 접근 지정을 private으로 설정한 멤버는 어떻게 접근할까요? priavate으로 접근 지정한 멤버는 파생 클래스에서도 접근할 수 없습니다. 분명히 상속받아 개체 내부에 있지만 가시성이 없어 접근할 수 없습니다. 이럴 때는 기반 클래스에서 protected로 접근 지정하여 파생 클래스에서 접근할 수 있게 해 주어야 합니다. 즉 protected 접..

[C++] 28. 파생 개체의 생성과 소멸 과정

이번에는 일반화 관계에 있는 파생 클래스 형식의 개체를 생성과 소멸 과정을 알아보기로 할게요. 파생 클래스 형식의 개체를 생성할 때는 기반 클래스를 생성한 후에 파생 클래스를 생성합니다. 실제 생성한 개체에는 기반 클래스에 정의한 멤버도 만들어지는 것이죠. 그리고 소멸할 때는 생성 과정의 역으로 파생 클래스의 소멸자를 수행한 후에 기반 클래스의 소멸자를 수행합니다. 다음은 이를 확인하기 위해 기반 클래스 음악가와 파생 클래스 피아니스트 클래스에 생성자와 소멸자를 추가하여 어떤 순서로 수행하는지 확인하기 위한 출력문을 작성한 예제 코드입니다. //파생 개체의 생성과 소멸 과정 #include #include using namespace std; class Musician { public: Musician(..

[C++] 27. 상속(일반화 관계) 개요

이제 OOP의 세 가지 주요 특징인 캡슐화, 상속, 다형성 중에 상속에 관해 알아볼게요. 상속은 다른 형식에 정의한 것을 마치 자신에서 정의한 것처럼 만드는 OOP의 특징입니다. 이러한 관계를 UML에서는 일반화 관계라 부르고 삼각형과 실선으로 관계를 표시합니다.일반화 관계는 “피아니스트는 음악가이다.”처럼 “이다.(is a)”로 나타낼 수 있는 관계입니다. 이 때 음악가처럼 일반적인 클래스를 기반 클래스라 말하며 피아니스트처럼 특수한 클래스를 파생 클래스라 부릅니다. C++에서 일반화 관계를 표현할 때 파생 문법을 이용합니다. 파생 문법은 파생 클래스를 정의할 때 기반 클래스를 다음처럼 나타냅니다. class Pianist : public Musician { }; 파생 클래스를 정의하면 기반 클래스에 ..

[c language] 117. 콜백

이번에는 함수 포인터를 콜백으로 이용하는 간단한 예를 살펴보아요. 정렬 알고리즘은 원소 형식이 무엇인지에 상관없이 대부분 같아요. 하지만 비교하는 것은 차이가 있죠. 만약 번호와 이름을 멤버로 갖는 학생 구조체 배열을 번호순으로 정렬한다면 멤버 번호로 비교해야 할 거예요. 이름순으로 정렬한다면 멤버 이름으로 비교해야겠죠. 이럴 때 비교하는 논리를 전달받아 형식에 관계없이 정렬하는 함수를 구현할 수 있어요. 이 때 비교하는 논리를 전달 받기 위해 함수 포인터를 사용해요. 호출하는 곳에서는 비교 함수를 정의하여 정렬 함수에 이를 입력 인자로 전달해요. 그리고 정렬 함수에서는 전달받은 비교 함수를 이용하여 정렬하는 것죠. 결국 피호출 함수인 정렬 함수에서 호출한 곳에서 정의한 비교 함수를 호출하는 것이므로 콜..

[c language] 116. 함수 포인터

함수 포인터는 시그니쳐를 원소 형식으로 취급해요.두 개의 정수 형식을 입력 인자로 받고 반환 형식이 정수인 함수 포인터 변수는 int (*fun)(int ,int); 처럼 선언할 수 있어요. 그리고 fun 포인터 변수에 함수 원형이 같은 함수 이름을 대입할 수 있죠. 함수 포인터 변수는 함수 호출과 같은 방법으로 사용할 수 있어요. 또한 typedef int (*Fun)(int ,int); 처럼 함수 포인터 형식명을 정의하여 Fun fun; 처럼 변수 선언에 사용할 수도 있죠. 예를 들어 두 개의 정수를 입력 인자로 받아 두 수의 합과 차, 곱, 나누기를 하여 결과를 반환하는 함수들이 있다고 가정해요. 그리고 typedef int (*Fun)(int,int); 처럼 함수 포인터 형식명을 정의하기로 해요...

[C language] 114. 도서 관리 프로그램 - 로딩

먼저 App에서는 파일을 읽기 모드로 열어야겠죠. 그리고 App의 정보를 파일에서 읽어오세요. 다른 물리 매체에 데이터를 선형으로 읽어와 프로그램 데이터가 되는 과정을 역직렬화라고 불러요. 역직렬화 함수에서는 마지막 부여한 장르 번호와 장르 개수를 로딩해야죠. 그리고 파일을 인자로 장르를 만들어 배열에 보관하세요. 파일로부터 장르를 만드는 함수에서는 역직렬화 과정이 필요해요. 장르번호, 장르명, 마지막 부여한 도서 번호를 파일에서 로딩하고 도서 개수를 로딩하세요. 그리고 파일에서 도서 개체를 만들어 배열에 보관하세요. 파일에서 도서 개체를 만드는 함수에서도 역직렬화를 수행하고 작업을 수행한 후에 App에서는 파일을 닫으세요.먼저 파일에서 데이터를 로딩하여 Book 개체를 생성하는 파일을 헤더 파일에 선언..

반응형