반응형

언어 자료구조 알고리즘 1251

[C++] 하향 캐스팅

6.3 하향 캐스팅 다형성은 캡슐화와 상속을 보다 효과적이고 현실 세계에 근접하게 표현할 수 있게 해주는 매력적인 특징입니다. 하지만 기반 클래스 형식 포인터 변수로 파생된 개체를 관리하는 것은 치명적인 단점을 가져오게 합니다. 만약, 기반 클래스 형식에서는 약속할 필요가 없는 메서드가 파생 클래스 형식에 있을 경우 해당 메서드의 접근 수준을 public으로 제공하여도 접근하지 못하게 됩니다. 이러한 약점을 보완하기 위해 많은 OOP언어에서는 런 타임에 파생 개체 형식으로 캐스팅하는 방법을 제공하고 있으며 이를 하향 캐스팅이라 합니다. C++언어에서는 dynamic_cast를 통해 하향 캐스팅을 제공하고 있습니다. dynamic_cast를 사용하면 관리되는 실 개체의 형식이 캐스팅이 가능하지 않다면 0을..

[C++] 메서드의 다형성

6.2 메서드의 다형성 기반 클래스 형식 포인터 변수로 파생된 개체를 관리를 할 수 있다는 것은 매우 매력적입니다. 하지만 모든 행위가 모두 동일하게 동작한다면 굳이 기반 클래스와 파생 클래스로 나눌 필요가 없겠지요. 기반 클래스 형식 포인터 변수로 관리하는 개체의 멤버 메서드를 호출할 때에 파생된 각 클래스에서 새롭게 정의한 메서드를 호출할 수 있게 할 수 있습니다. 이처럼 사용하는 곳에서 호출하는 메서드는 동일하지만 실제 동작하는 모습이 다를 수 있다는 것도 중요한 다형성의 특징입니다. 만약, 오케스트라의 모든 음악가가 같은 연주를 한다면 어떤 느낌이 들까요? 아마도 각 음악가가 연주하는 모습이 다르지만 각각의 연주가 조화를 이루기 때문에 더욱 더 장엄하고 아름답게 들리는 것이로 생각됩니다. 프로그램..

[C++] 개체의 다형성

6.1 개체의 다형성 파생을 통해 얻을 수 있는 이점 중의 하나는 기반 클래스 형식의 포인터 변수로 파생된 개체를 관리할 수 있다는 것입니다. 오케스트라를 형성하는 여러 종류의 음악가를 기반 클래스인 음악가에서 파생을 시켜 피아니스트, 드러머 등을 정의함으로써 하나의 컬렉션에서 관리하는 것은 참으로 매력적인 일이 아닐 수 없습니다. 이처럼 기반 클래스 형식의 포인터 변수로 파생된 개체를 관리를 할 수 있기 때문에 특정 변수가 관리하는 개체는 다양한 형태의 개체를 관리할 수 있게 됩니다. 이때 기반 클래스 형식의 포인터 변수로 파생된 개체 인스턴스를 대입할 때 묵시적으로 상향 캐스팅이 됩니다. 그리고, 이러한 특징은 다형성의 일부가 됩니다. [그림 6.1] Musician.cpp #include "Musi..

[C++] 파생 시에 액세스 지정

5.3 파생 시에 액세스 지정 지금까지 파생을 표현할 때 기반 클래스의 접근 수준을 변경없이 파생하였습니다. 이 외에도 protected 상속과 private 상속이 있는데 어떠한 차이가 있고 어떠한 경우에 사용될 수 있는지 알아봅시다. 파생할 때 기반 클래스 명 앞에 붙는 접근 지정자는 기반 클래스의 멤버들의 가시성이 허용되는 수준 중에 가장 넓은 가시성을 갖을 수 있는 수준을 지정하는 것입니다. 만약, protected 상속을 하였을 경우 기반 클래스에 public인 멤버는 가시성이 protected보다 넓을 수 없기 때문에 protected로 강화됩니다. 주의할 것은 기반 클래스의 private 멤버는 어떠한 상속이든지에 상관없이 파생된 스코프에서는 가시성이 없습니다. IntArr.h #pragma..

[C++] 무효화 된 멤버 사용하기

5.2.1 무효화 된 멤버 사용하기 기반 클래스에 특정 메서드의 행위를 파생 클래스에서 해당 행위도 하고 다른 행위도 하게 하려고 할 때에는 어떻게 구현해야 할까요? 이 경우에는 무효화 된 기반 클래스의 멤버 메서드를 파생된 곳에서 기반 클래스 명과 스코프 연산자를 붙여 메서드를 호출하면 무효화 된 멤버를 사용할 수 있습니다. 앞선 예제에서 EH 프로그래머의 프로그래밍 메서드를 시간을 입력 인자로 받는 것으로 수정하고 해당 행위에서는 먼저 "생각한 것을 문서화 한다."를 수행하고 기반 클래스에 무효화 된 메서드를 활용하는 예제를 보여 드리겠습니다. Programmer.h와 Programmer.cpp는 같다고 했을 때 바뀌는 부분만 살펴봅시다. EHProgrammer.cpp #include "EHProgr..

[C++] 무효화

5.2 무효화 파생을 이용해서 일반화 관계를 형성했을 때 파생 클래스에서 기반 클래스에 정의한 이름과 같은 이름으로 메서드를 만들면 기반 클래스에 정의한 메서드는 무효화가 됩니다. 기반 클래스에 있는 멤버 메서드들 중에 구체적인 구현을 다르게 하고자 한다면 무효화를 이용하면 가능합니다. 만약, 일반 프로그래머가 있고 EH 프로그래머가 있는데 대부분의 행위에 있어 EH 프로그래머는 일반 프로그래머와 같게 일을 한다고 가정을 합시다. 하지만 일반 프로그래머가 프로그래밍을 할 때 "생각하면서 코딩을 한다."와 같이 하는데 EH 프로그래머가 프로그래밍을 할 때는 "생각한 것을 문서화 하고 이를 보면서 코딩을 한다."고 해 볼께요. 이 경우에 일반 프로그래머의 프로그래밍이라는 메서드는 무효화가 됩니다. 무효화의 ..

[C++] 파생 개체 생성 과정 및 초기화

5.1.2 파생 개체 생성 과정 및 초기화 파생 개체가 생성될 때는 먼저 기반 클래스 부분이 형성된 후에 파생 클래스 부분이 형성됩니다. 즉, 기반 클래스의 생성자 메서드가 수행된 후에 파생 클래스의 생성자 메서드가 수행됩니다. 그리고 파생 개체가 소멸될 때는 역으로 파생 클래스의 소멸자 메서드가 수행되고 나서 기반 클래스의 소멸자 메서드가 수행됩니다. 만약, 기반 클래스에 입력 매개 변수가 없는 생성자(기본 생성자)가 정의되지 않고 매개 변수가 있는 생성자만 정의된 경우에는 파생 개체가 생성될 때 어떻게 될까요? 파생 개체가 생성되기 위해선 기반 클래스의 생성자 메서드 부분이 수행이 되어야 하는데, 인자를 어떤 값으로 전달할 것인지 컴파일러가 결정하지 못합니다. 이 경우에 파생된 클래스의 소스 코드에서..

[C++] 일반화 관계와 파생

5.1 일반화 관계 일반화 관계는 음악가와 피아니스트처럼 “피아니스트는 음악가이다.”라는 논리적 관계를 형성하는 관계를 말합니다. C++에서는 이와 같은 관계를 효과적으로 사용할 수 있도록 파생에 관련한 문법을 제공하고 있으며 이러한 특징은 OOP의 상속에 속합니다. [그림 5.1] 5.1.1 일반화 관계와 파생 C++에서 일반화 관계를 표현할 때 파생에 관련된 문법을 이용합니다. 파생을 표현할 때는 파생 클래스에서 어느 클래스를 기반 클래스로 할 것인지를 다음과 같이 명시하면 됩니다. class Derived : public Base{}; 파생을 표현할 때 기반 클래스의 접근 지정된 것을 파생된 것에서 그대로 계승하고자 할 때 public 키워드를 명시하면 기반 클래스의 각 멤버의 접근 지정도 동일하게..

[C++] 실현관계 (Realization)

4. 5 실현관계 (Realization) 실현관계는 추상적으로 행위에 대한 약속만 정의하고 이를 기반으로 약속된 행위를 구체적으로 정의할 경우에 약속하는 형식과 구체적 정의를 하는 형식 간의 관계입니다. 여기에서 행위에 대한 약속을 정의한 추상 형식을 인터페이스라 부르며 인터페이스를 구현 약속하는 클래스와의 관계를 실현관계라 합니다. 이때 약속된 행위는 묵시적으로 접근 지정자가 public입니다. [그림 4.10] C++ 언어에서는 행위에 대한 추상적인 약속은 순수 가상 함수를 형식 내에 캡슐화하는 방식으로 할 수 있습니다. 순수 가상 함수를 형식 내에 캡슐화할 때에는 virtual 키워드를 앞에 붙이고 메서드 뒤에 =0;를 명시하면 됩니다. 그리고 소스 코드에서 해당 형식에 대한 구체적 구현은 하지 ..

[C++] 의존 관계 (Dependency)

4. 4 의존 관계 (Dependency) 학생과 시험에서처럼 "학생의 성적은 시험 문제의 난이도에 영향을 받는다." 와 같이 특정 개체에 따라 특정 행위에 영향이 생기는 관계를 얘기합니다. 그리고 공장과 상품처럼 "공장에 상품을 주문하면 상품을 생산한다." 와 같이 특정 형식의 개체 생성을 책임질 때에도 의존 관계로 표시합니다. [그림 4.8] 먼저, 학생이 시험을 보았을 때 성적이 시험의 난이도에 영향을 받는 경우의 예제 코드를 살펴봅시다. Stu.cpp #include "Stu.h" Stu::Stu(string _name) { name = name; score = -1; } Stu::~Stu(void) { } void Stu::TestAnExamination(Examination *ex) { sco..

반응형