이 서평은 이지스퍼블리싱의 서평단으로 선정되어 출판사로부터 책을 제공받아 작성되었습니다.
https://product.kyobobook.co.kr/detail/S000212764031
C++은 CS 영역에서 중요한 위치를 차지하고 있다. 시스템 프로그래밍, 게임 개발, 임베디드 소프트웨어, 고성능 서버 및 클라이언트 애플리케이션 등 다양한 개발 분야에서 사용되는 범용적인 프로그래밍 언어이다.
C++은 단일 패러다임에 제한되어 있지 않다. 객체지향, 함수형 프로그래밍을 포함한 다양한 프로그래밍 스타일을 지원한다. 또한 메모리 관리와 저수준 시스템 접근 능력을 제공함으로써 개발자가 최적화된 소프트웨어를 설계하고 구현하게 해준다.
이 책은 C++의 기초부터 STL, 객체지향 SOLID 원칙, 템플릿, 새로운 버전에서의 변경점 등 C++에 관련된 내용들을 다양하게 다루어서 좋다. 단순 문법을 넘어 다양한 측면을 이해할 수 있도록 도와줘 객체지향을 공부하고자 하는 대학생들에게 유용할 것 같다.
들어가기에 앞서, 저자님께 궁금한 점이나 오탈자 발견 시 아래 링크(Github)로 가서 문의드리면 된다.
https://github.com/mystous/DoItCPP/issues
첫째마당: C++ 프로그래밍 기초
01 C++ 프로그래밍 시작하기
이 장에서는 C++ 프로그래밍 언어의 기본 개념과 역사를 소개한다. C언어와의 주요 차이점, 컴파일 과정의 특징, 표준화 제정은 누구에 의해 이루어지는지 등 C++이 지금까지 오기에 어떤 과정을 거쳤는지에 대해 알 수 있다.
추가적으로 저수준 액세스, 추상화, 안정성, 비독점, 발전 등 주요 특징과 어디에 활용되는지, 그리고 개발 생태계가 어떻게 구성되어 있는지에 대한 설명이 포함되어 있다.
컴파일러, 디버거, 라이브러리 같은 도구들이 어떤 역할을 하며 개발자가 일상적으로 사용하는 다양한 개발 툴과 통합 개발 환경(IDE)의 예시들이 언급된다. 제공되는 라이브러리들은 게임 개발, 시스템 프로그래밍 등 다양한 분야에서 C++의 활용도를 높여주는데 큰 역할을 하고 있다. 요즘 유행하는 인공지능 관련 라이브러리가 눈에 띤다.
POCO C++ Libraries - Reference Library
C++ 라이브러리 이해하기 | TensorFlow Lite
C++의 다양한 사용 사례와 많은 개발자 커뮤니티가 어떤 것이 있는지에 대해 알아가면서 이 언어가 오늘날까지 왜 널리 사용되고 있는지 이해할 수 있게 될 것이다.
02 변수와 연산자
C++은 C언어를 기반으로 발전된 프로그래밍 언어이기 때문에 C언어의 문법을 대부분 계승했다. C언어를 이미 배운 경험이 있다면 그렇게 어렵지는 않을 것이다.
다만 변수와 연산자 부분에서 중요한 차이점 중 하나가 바로 네임스페이스의 사용이다. 함수, 변수 등에 범위를 부여해 여러 라이브러리를 포함할 때 충돌하는 것을 방지하려고 사용한다.
네임스페이스는 함수, 변수 등의 식별자에 대한 범위(Scope)를 정의해 다양한 라이브러리를 사용할 때 발생할 수 있는 이름 충돌을 방지하는 데 사용한다.
03 포인터와 메모리 구조
포인터 변수, 데이터 접근, 다중 포인터, 배열 원소 접근 등 C언어에서도 있었던 주제들을 볼 수 있다. 이와 더불어 스택과 힙 같은 메모리 구조를 통해 프로그램의 동적 메모리 관리 방법에 대해서도 소개하고 있다.
C언어와 비교했을 때 C++에서의 주요 차이점 중 하나는 바로 동적 메모리 할당 방식에 있다. C++에서는 new 키워드를 사용하여 동적 메모리를 할당하고 delete 키워드를 사용해 할당된 메모리를 해제한다. C언어에서 malloc과 free 함수를 사용하는 방식과 대비됨을 볼 수 있다.
C++의 new와 delete는 타입 안전성을 제공해 생성된 객체의 생성자와 소멸자를 자동으로 호출하는 등의 추가적인 기능을 제공한다. 개발자가 놓치고 선언하지 못하는 경우를 대비해 안전하고 직관적으로 메모리를 관리할 수 있게 도운다. 더 자세한 내용은 이 책의 [7-3장 생성자와 소멸자]에서 자세하게 설명하고 있다.
04 실행 흐름 제어
조건문과 반복문은 프로그래밍 언어의 핵심 요소로 if, else, else if, switch 문과 같은 조건문을 통해 특정 조건에 따라 다른 코드 블록을 실행할 수 있다.
반복문에는 while, do~while, for 문으로 특정 조건이 만족하는 동안 코드 블록을 반복해서 실행한다. C언어와 동일하게 적용된다.
추가적으로 표현식과 구문의 차이점에 대해 설명한다. 표현식(Expression)은 하나 이상의 값, 변수, 연산자의 조합으로 구성되어 값을 평가해 결과를 반환한다. 예를 들어 1 + 2 또는 x * y와 같은 식이 표현식에 해당한다.
반면 구문(Statement)은 프로그램이 실행해야 할 최소한의 독립적인 집합이다. int x = 5; 또는 return x; 같은 명령문이 구문이다.
05 예외 처리하기
프로그래밍에서 예외는 문법적 오류와는 다르게 실행 중에 발생하는 의도하지 않은 오류를 말한다. 프로그램이 코드적으로는 완벽하다 하더라도 메모리 부족이나 저장 공간의 문제와 같은 물리적인 이슈로 인해 예상치 못한 오류가 발생할 수 있다.
실행 흐름 중 발생하는 오류에 대응하는 방법으로 예외 처리가 사용된다.
예외 처리는 try, catch, throw 문을 사용하여 구현된다. try 블록 안에는 예외가 발생할 가능성이 있는 코드를 넣고, catch 블록은 해당 예외를 캐치하여 처리하는 코드를 포함한다. 예외는 throw 문을 사용하여 명시적으로 발생시킬 수 있으며 발생한 예외는 가장 가까운 catch 블록에 의해 처리된다.
함수 내에서 발생한 예외가 해당 함수 내의 catch 블록에서 처리되지 않을 경우 그 예외는 함수를 호출한 쪽으로 전달된다. 이러한 현상을 스택 풀기$_{unwinding}$라고 한다.
스택 풀기는 예외가 발생한 지점부터 예외를 처리할 수 있는 catch 블록이 나올 때까지 호출 스택을 거슬러 올라가는 과정이다. 이 과정에서 함수의 호출 스택이 해제되며 각 함수의 종료 조건이나 객체의 소멸자가 실행되는 등의 부수적인 작업이 수행된다.
C++에서는 어설션(assertion)을 이용한 예외 처리 기법도 제공한다. 어설션$_{assertion}$은 프로그램이 특정 조건을 만족하지 않을 때, 즉 예상치 못한 상황을 감지할 때 실행을 강제로 중단시키는 도구이다. 개발 과정에서 논리적 오류를 조기에 발견하고 디버깅을 도와준다.
둘째마당: 객체지향 프로그래밍
06 객체지향과 클래스
C언어에서 C++로의 전환은 여러 가지 변화를 가져왔지만 그 중 하나는 객체지향 프로그래밍(OOP)의 도입이다.
이 책은 프로그래밍 패러다임을 근본부터 설명해 절차적 프로그래밍의 장단점을 다루고, 이를 통해 객체지향 프로그래밍이 왜 필요한지에 대한 설명을 제공한다. 마지막에는 객체지향 프로그래밍의 핵심 특징과 원리에 대해서도 자세히 소개한다.
클래스와 객체의 정의 방법, 객체의 인스턴스화 및 활용 방법이 코드로 작성되어 쉽게 따라할 수 있다.
특히 자동차 어댑티브 크루즈 컨트롤 시스템을 예제로 사용한 부분은 객체지향 프로그래밍의 개념을 실생활과 밀접하게 연결시켜 준다.
객체지향의 주요 개념인 캡슐화, 상속, 다형성 등을 실제로 어떻게 적용할 수 있는지 보여주며 복잡한 시스템을 어떻게 효과적으로 설계하고 구현할 수 있는지 보여준다.
07 객체지향 프로그래밍 특징
이 장에서는 객체지향 프로그래밍의 핵심 특징인 추상화와 캡슐화에 대해 설명하고 있다.
추상화는 복잡한 실제 세계의 개념들을 단순화하여 프로그램에서 쉽게 다룰 수 있도록 하는 과정이다. 캡슐화는 객체의 세부 구현 내용을 외부로부터 숨기고 필요한 정보만을 외부에 노출시켜 객체의 독립성을 높이는 기법이다. 이 방법으로 객체 간의 결합도를 낮추고 유지보수성을 향상시킬 수 있다.
상속성과 다형성 개념은 UML 다이어그램과 함께 그림으로 설명되어 이해하기 쉽게 표현되어 있다. 상속성은 하나의 클래스가 다른 클래스의 특성을 물려받을 수 있게 해 코드 재사용성을 높여준다.
다형성은 같은 인터페이스나 메소드 호출이 다양한 방식으로 실행될 수 있게 하는 특징으로 유연하고 확장 가능한 코드 설계를 가능하게 한다.
객체의 생성(new)과 제거(delete) 과정에서는 생성자와 소멸자가 자동으로 호출되는 과정을 다룬다. 객체가 사용하는 자원을 초기화하거나 해제할 때 중요한 역할을 해 멤버 변수의 종류에 따라 초기화 방법이 어떻게 다른지 소개한다.
복사 생성자의 경우 얕은 복사와 깊은 복사의 개념을 설명해 객체를 복사할 때 발생할 수 있는 원인에 대해 설명한다.
소멸자에서는 기본 소멸자와 가상 소멸자에 대한 설명을 통해 객체가 소멸될 때 리소스 해제가 올바르게 이루어지는 방식을 설명한다. 특히 상속 관계에 있는 객체들이 소멸될 때 중요한 개념이다.
this 포인터는 객체가 자신을 참조할 수 있도록 하는 포인터로 메서드 내에서 현재 객체의 멤버에 접근하는 데 사용된다. 함수와 연산자 오버로딩에서도 활용될 수 있다. 예를 들어 연산자 오버로딩을 구현할 때 this 포인터를 사용하면 현재 인스턴스의 멤버 변수나 함수에 접근하여 연산자의 기능을 클래스 내부적으로 정의할 수 있다.
접근 지정자는 클래스 멤버의 접근 수준을 제어하는 키워드로 public, protected, private 세 가지가 있다. 클래스의 캡슐화를 강화하고 객체의 데이터와 메서드를 보호해 사용자에게 필요한 인터페이스만을 노출시킨다.
friend 키워드는 특정 함수나 다른 클래스가 개인적으로 지정된 클래스의 protected나 private 멤버에 접근할 수 있게 허용하는 기능을 가진다. 특정 상황에서 유용할 수 있지만 friend 키워드의 사용은 캡슐화 원칙에 반하고 클래스 간의 결합도를 높여서 유지보수성을 저해할 수 있으므로 가능한 한 제한적으로 이루어져야 한다.
08 객체지향을 돕는 기능들
이 장에서는 객체지향 프로그래밍을 돕는 C++ 언어의 기능과 활용 방법을 소개하는데 조금 어렵다. 실전에서 요긴하게 사용할 수 있어 차분하게 공부한다면 실력을 키울 수 있을 것이다.
컴포지션(composition)과 어그리게이션(aggregation)은 객체지향 설계에서 클래스 간의 관계를 정의하는 중요한 개념이다. 컴포지션은 한 클래스가 다른 클래스를 포함하는 더 강한 소유 관계(part-of)를 나타내고 어그리게이션은 보다 약한 연관 관계(has-a)를 의미한다.
가상 함수와 동적 바인딩은 C++의 다형성을 지원하는 메커니즘이다.
가상 함수는 기반 클래스에서 선언되고 파생 클래스에서 재정의될 수 있는 멤버 함수로 동적 바인딩을 통해 실행 시점에 객체의 실제 타입에 따라 호출되는 함수가 결정된다. 이 과정은 가상 함수 테이블$_{vtable}$을 사용해 관리된다.
순수 가상 함수는 구현을 제공하지 않고 파생 클래스에서 반드시 구현해야 하는 가상 함수이며 하나 이상의 순수 가상 함수를 포함하는 클래스는 추상 클래스로 간주된다. 가상 소멸자는 파생 클래스의 객체가 기반 클래스 포인터를 통해 삭제될 때 파생 클래스의 소멸자를 올바르게 호출하기 위해 사용된다.
추상 클래스는 하나 이상의 순수 가상 함수를 포함하여 직접 인스턴스화할 수 없는 클래스이다. 인터페이스와 구현을 분리하는 데 유용하고 파생 클래스에 특정 함수를 구현하도록 강제하는 방법을 제공한다.
정적 멤버는 클래스의 모든 인스턴스가 공유하는 멤버 변수나 함수이다. 정적 멤버 변수는 클래스의 모든 객체에 걸쳐 단 하나만 존재하고 정적 멤버 함수는 객체가 아닌 클래스 자체에 소속되어 인스턴스 없이도 호출할 수 있다. 특정 데이터를 클래스의 모든 인스턴스가 공유하거나 클래스 레벨에서 작업을 수행할 필요가 있을 때 유용하게 활용된다.
09 객체지향 설계 원칙
객체지향 설계 원칙인 SOLID에 대해 다루고 있다. 이 원칙들은 소프트웨어의 유지보수성, 확장성 및 재사용성을 높이는 데 목적을 둔다.
단일 책임 원칙${Single \space Responsibility \space Principle; \space SRP}$, 개방 폐쇄 원칙${Open/Closed \space Principle, \space OCP}$, 리스코프 치환 원칙${Liskov \space Substitution \space Principle, \space LSP}$, 인터페이스 분리 원칙${Interface \space Segregation \space Principle, \space ISP}$, 의존성 역전 원칙$_{Dependency \space Inversion \space Principle, \space DIP}$ 각각의 원칙에 대해 C++의 인터페이스와 추상 클래스를 포함해 UML 다이어그램으로 시각화화해 설명한다.
10 템플릿
둘째마당의 마지막 장에서는 템플릿을 다룬다. 템플릿이란 코드를 좀 더 일반화하여 다양한 타입에 대해 동일한 작업을 수행할 수 있게 하는 C++의 특징 중 하나다.
함수를 만들어 내는 경우에는 함수 템플릿, 클래스를 만들어 내는 경우에는 클래스 템플릿이 된다. 템플릿 문법을 사용하면 타입에 의존하지 않는 범용적인 코드를 작성할 수 있다.
예를 들어 정수형 배열과 실수형 배열을 정렬하는 함수를 각각 다르게 작성하는 대신 템플릿을 사용해 하나의 정렬 함수로 다양한 타입의 배열을 정렬할 수 있다.
셋째마당: 라이브러리 활용
11, 12 C++ 표준 라이브러리
C++ 표준 라이브러리는 방대한 양을 자랑하지만 개발자들이 자주 사용하는 핵심 라이브러리 위주로 구성되어 있다. 이들 라이브러리는 입출력, 문자열 처리, 컨테이너, 알고리즘, 파일 처리 등 다양한 요구들을 충족시키는 기능들이 포함되어 있다.
컨테이너 라이브러리는 데이터를 저장하고 관리하는 데 사용되는 큐, 덱, 스택, 셋, 맵 등과 같은 자료구조 라이브러리라 생각하면 된다. 알고리즘은 오름차순, 내림차순, 정렬, 이진 탐색 등이 설명되어 있다.
알고리즘 라이브러리 부분에서는 오름차순 정렬, 내림차순 정렬, 일반 정렬, 이진 탐색 등이 설명되어 있다. 알고리즘 문제 해결에 자주 사용되는 라이브러리로 문제 푸는데 경험이 있는 사람들에게는 특히 도움될 것 같다.
넷째마당: 모던 C++ 프로그래밍
모던 C++에서는 여러 버전에 걸쳐 다양한 새로운 기능과 개선사항이 추가되었다. C++98부터 최근 버전까지 각각의 업데이트에서 어떤 기능이 추가되었는지 설명한다.
예를 들어 자동 타입 추론을 가능하게 하는 auto, 강력한 타입 열거형을 제공하는 enum class, 타입을 추론하는 decltype, 널 포인터를 명확히 표현하는 nullptr, 컴파일 시간에 계산을 수행하는 constexpr 등의 새로운 데이터 타입과 키워드가 소개되고 있다.
C++11부터는 현대적인 C++ 프로그래밍을 위한 새로운 구문과 기능이 대거 도입되었다.
튜플과 구조적 바인딩은 데이터를 묶고 분해하는 방법을 제공한다. 람다 표현식은 함수를 간결하게 정의하는 방법으로 소개한다.
더욱 발전된 구문으로는 폴드 표현식과 3방향 비교 연산자, using 키워드가 있다.
폴드 표현식은 가변 템플릿 인자를 쉽게 처리할 수 있게 해주고 3방향 비교 연산자는 값을 비교하는 새로운 방식을 제공한다. using 키워드는 타입 별칭을 정의하거나 네임스페이스를 선언하는 데 사용된다.
총평
이 책은 C++의 기본 개념에서 시작하여 모던 C++의 고급 주제에 이르기까지 광범위하게 다루고 있다.
단순히 기초 정보를 넘어서 고급 내용까지 포함하고 있어 C++의 다양한 사용 분야, 객체지향 프로그래밍의 핵심, 템플릿의 유연한 활용법, 그리고 STL 등을 종합적으로 소개한다.
객체지향 프로그래밍의 깊은 이해를 추구하는 대학생들뿐만 아니라 C++의 최신 기능에 대해 알고자 하는 현업 개발자들에게도 의미있는 책인 것 같다.
'Life > 독서 기록' 카테고리의 다른 글
[서평] IT 인프라 입문서 - 그림으로 공부하는 IT 인프라 구조 개정판 (0) | 2024.04.20 |
---|---|
[서평] 팀플부터 협업까지 - 일 잘하는 팀장 (0) | 2024.04.15 |
[서평] 개념부터 활용 전략과 미래 전망까지 - 멀티모달 생성 AI 인사이드 (2) | 2024.03.24 |
[서평] 비전공자도 간단하게 - 누구나 쉽게 캔바(canva)로 끝내는 콘텐츠 디자인 (0) | 2024.03.05 |
[서평] 대학 강의 실전 압축 - 컴퓨터 시스템 딥 다이브 (0) | 2024.02.24 |
컴퓨터 전공 관련, 프론트엔드 개발 지식들을 공유합니다. React, Javascript를 다룰 줄 알며 요즘에는 Typescript에도 관심이 생겨 공부하고 있습니다. 서로 소통하면서 프로젝트 하는 것을 즐기며 많은 대외활동으로 개발 능력과 소프트 스킬을 다듬어나가고 있습니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!