전체 글 129

38장 함수 객체

38-1 함수 객체 가. 함수 객체 STL의 알고리즘들은 전역 함수가 처리하여 문제를 풀기 위한 반복자 구간, 검색 대상, 채울 값 따위의 정보들이 함수의 인수로 전달된다. 알고리즘 함수들은 입력된 정보를 바탕으로 알아서 동작하지만 어떤 함수들은 내부에서 모든 동작을 다 처리하지 않거나 할 수 없는 경우도 있다. 검색하고자 하는 값이 정확하게 어떤 조건인지, 정렬을 위해 요소를 비교할 때 어떤 방식으로 비교할 것인질르 함수가 마음대로 결정할 수 없다. 이럴때 함수에게 좀 더 구체적인 처리 방식을 지정하기 위해 사용자가 미리 만들어 놓은 함수 객체를 전달한다. 똑같은 함수를 호출하더라도 함수 객체를 어떻게 작성하는가에 따라 알고리즘의 활용도가 대폭 향상되는 효과가 있다. for_each 함수를 사용하면 순..

37장 STL 개요

37.1 STL 소개 37.1.1 일반화 프로그래밍 프로그램은 자료 구조와 알고리즘으로 구성된다. 자료구조는 처리하고자 하는 데이터를 표현하는 방법이고 알고리즘은 이 자료들을 가공하여 유용한 정보를 생산하는 기법이다. 좋은 프로그램을 만들려면 이 두 가지가 모두 필요하며 어느 한 쪽이 허술하면 전체적인 프로그램의 질이 떨어진다. 어떤 자료구조를 사용할 것인가는 프로그램의 특수한 상황에 따라 달라진다. 각 자료 구조마다 고유한 특징과 장단점이 있어서 모든 형태의 데이터에 다 어울리는 이상적인 자료구조는 없으며 상황에 따라 가장 효율적인 자료구조를 선택해야 한다. OOP 이후의 또다른 시도인 STL은 일반화 프로그래밍 기법이라는 좀 더 발전된 개념의 재사용성을 제공한다. 일반화(Generic)는 객체 지향의..

36장 표준 라이브러리

36-1 iostream 가. 입출력 스트림의 구조 C++의 표준 입출력 스트림은 여러 가지 복잡한 상황에 대해서도 입출력을 처리할 수 있도록 확장 가능한 클래스 계층을 구성하고 있다. C++의 헤더 파일을 기준으로 그려본 간단한 클래스 계층도이다. ios_base 클래스는 입출력과 관련된 여러 가지 상수나 플래그들을 가지며 이 클래스로부터 입출력 클래스들이 파생된다. 출력 클래스인 basic_ostream의 선언문은 다음과 같다 template class basic_ostream : virtual public basic_ios { ... :: _Elem 출력하는 데이터의 기본 타입이다. 통산 문자열 형태로 출력되므로 가거에는 char 타입의 문자들을 출력했으나 모든 문자를 16비트 코드를 표현하는 유니..

34장 네임 스페이스

34-1 네임 스페이스 가. 명칭의 충돌 C/C++ 소스를 구성하는 7가지 요소 중의 하나인 명칭(Identifier)은 변수, 함수, 타입 등 다양한 요소를 정의할 때 사용한다. 몇 가지 규칙만 지키면 자유롭게 정의할 수 있으며 그래서 가급적이면 기억하기 쉽고 대상을 명확하게 표현할 수 있는 이름을 붙인다. 그러나 프로그램이 복잡해지고 규모가 커질수록 더 많은 명칭이 필요해져서 고유한 이름을 붙이는 일이 점점 더 어려워지고 있다. 게다가 팀 단위로 작업할 때는 혼자서 명칭을 다 만드는 것이 아니며 외부 라이브러리를 가져다 쓰는 일도 흔해져서 우연히 명칭이 충돌하는 일이 잦아졌다. 외부 라이브러리끼리 명칭이 충돌하면 수정할 수도 없어 한쪽 라이브러리의 사용을 포기해야 하는 곤란한 상태가 되기도 한다. 그..

33장 타입 정보

33-1 RTTI 가. 실시간 타입 정보 RTTI는 RunTime Type Information의 약자이며 실시간 타입 정보라는 뜻이다. 일반적으로 변수의 이름이나 구조체, 클래스의 타입은 컴파일러가 컴파일을 하는 동안에만 필요할 뿐이며 이진 파일로 번역되고 나면 이 정보들은 필요가 없다. 변수의 타입은 읽어들일 길이와 비트를 해석하는 정보로만 사용되며 기계어 수준에서는 길이와 비트해석 방법에 따라 생성되는 기계어 코드가 달라진다. 클래스도 마찬가지로 기계어로 바뀌면 구조체와 똑같되 다만 가상 함수가 있을 때 vtable을 가리키는 포인터를 하나 더 가진다는 정도만 다르다. 다만 첫 번째 인수가 this로 고정되어 있는 호출 규약을 사용하므로 이 함수를 호출 할 때는 항상 호출 객체의 포인터가 같이 전달..

32장 예외 처리

32-1 예외 가. 전통적인 예외 처리 예외(Exception)란 프로그램의 정상적인 실행을 방해하는 조건이나 상태를 의미하는데 프로그램을 잘못 작성해서 오작동하거나 다운되게 만드는 에러(Error)와는 다르다. 원칙적으로 에러는 개발 중에 모두 수정해야 하는데 모르고 그냥 남겨두지 않을 것이다. 최종 릴리즈할 때까지 미처 발견하지 못하면 이것을 버그라고 부르며 그 중에서도 아주 악질적인 에러를 버그라고 부른다. 예외란 버그와는 달리 제대로 만들었지만 원하는 대로 동작하지 못하게 방해하는 외부의 불가항력적인 상황을 말한다. 프로그램을 아무리 치밀하게 논리적으로 잘 작성하더라도 예외는 항상 발생할 수 있는데 왜냐하면 작성 시점에서 실행 시의 모든 상황을 정확하게 예측 할 수 없기 때문이다. 항상 정해진 절..

31장 템플릿

31.1 함수 템플릿 31.1.1 타입만 다른 함수들 C++은 여러 가지 개발 방법을 지원하는 멀티 패러다임 언어라고 하는데 적어도 다음 세 가지 방법으로 개발 할 수 있다. 구조적 프로그래밍 C언어와 마찬가지로 함수 위주로 프로그램을 작성할 수 있다. 객체지향 프로그래밍 캡슐화, 추상화를 통해 현실 세계의 사물을 모델링할 수 있으며 상속과 다형성을 지원하기 위한 여러가지 언어적 장치를 제공한다. 일반화 프로그래밍 임의 타입에 대해 동작하는 함수나 클래스를 작성할 수 있다. 객체 지향보다 재사용성과 편의성이 더 우수하다. 일반화 프로그래밍은 주로 C++ 템플릿에 의해 지원되며 C++ 표준 라이브러리가 일반화의 좋은 예이다. 템플릿은 C++이 일반화를 위해 제공하는 가장 기본적인 문법이므로 템플릿에 대한 ..

30장 다형성

30.1 가상 함수 가. 객체와 포인터 가상 함수란 클래스 타입의 포인터로 멤버 함수를 호출 할 때 동작하는 특별한 함수이다. 객체 지향의 중요한 특징인 다형성을 구현하는 문법적 기반이 바로 가상 함수이다. Human h("aa"); Student s(""ss", 9090); h = s // 가능 s = h // 에러 부모 클래스의 객체인 h가 자식 클래스의 객체인 s를 대입받는 것은 논리적으로 가능하다. 왜냐하면 h가 대입받을 모든 멤버가 s에 있기 때문이다. is a관계가 성립된다. s와 h에 동시에 존재하는 모든 멤버가 h로 대입되며 s에는 있지만 h에는 없는 멤버는 대입에서 제외된다. h = s 대입에 의해 h는 s가 가지고 있는 이름 정보를 가지게 될것이다. 그러나 대입은 가능하지만 우변의 정보..

29장 상속

29-1 상속 가. 클래스 확장 상속은 캡슐화, 추상화와 함께 객체 지향 프로그래밍의 중요한 특징 중 하나이다. 캡슐화와 추상화는 객체가 온전한 부품이 될 수 있는 방법을 제공하는데 비해 상속은 클래스를 좀 더 쉽게 만들 수 있는 고수준의 재사용성을 확보하고 클래스간의 계층적인 관계를 구성함으로써 객체 지향의 또 다른 큰 특징인 다형성의 문법적 토대가 된다. 상속을 하는 목적 또는 상속에 의한 효과는 다음 세 가지로 간략하게 요약할 수 있다. 기존의 클래스를 재활용한다. 가장 기본적인 효과이다. 공통되는 부분을 상위 클래스에 통합하여 반복을 제거하고 유지, 보수를 편리하게 한다. 공동의 조상을 가지는 계층을 만듬으로써 객체의 집합에 다형성을 부여한다. 상속을 할 때 원본 클래스가 어떤 것이라는 것을 밝히..

28장 연산자 오버로딩

28.1 연산자 함수 28.1.1 기본형의 연산자 연산자를 오버로딩 할 수 있다는 것은 C++ 언어의 큰 특징이며 클래스가 타입임을 보여주는 단적인 예라고 할 수 있다. 조금 어렵기는 하지만 문법이 체계적이어서 이해하고 나면 언어의 질서를 느낄 수 있으며 오히려 재미있기도 하다. 덧셈 연산문의 예 int i1=1, i2=2 ; double d1=3.3, d2=4.4 ; int i = i1 + i2 ; // 정수 덧셈 double d = d1 + d2 ; // 실수 덧셈 정수형과 실수형은 길이도 다르고 비트 구조도 상이해서 각 타입을 더하는 알고리즘이 분명히 다르겠지만 똑같은 연산자로 두 타입의 덧셈이 가능한 것이다. 이렇게 되는 이유는 덧셈 연산자가 피연산자의 타입에 따라 오버로딩 되어 있기 때문이다. ..