C++의 std::map은 키(key)와 값(value)을 하나의 쌍(pair)으로 묶어 저장하는 연관 컨테이너입니다. 맵 내부에는 std::pair 객체들이 저장되며, 각 pair는 하나의 키와 그에 대응하는 값을 담고 있습니다. 키와 값은 템플릿으로 구현되어 있기 때문에 int, char, string 등 어떤 자료형이든 자유롭게 사용할 수 있습니다.이러한 맵을 순회할 때 가장 간결하고 가독성 좋은 방법이 바로 C++11부터 도입된 범위 기반 for 루프(range-based for loop)입니다. 루프 변수를 auto&
이 글에서는 C++의 프록시(Proxy) 클래스가 무엇인지 살펴보겠습니다. 프록시 클래스는 기본적으로 프록시 디자인 패턴을 구현한 것으로, 한 객체가 다른 클래스를 대신하여 수정된 인터페이스를 제공하는 방식입니다. 간단한 예제를 통해 그 개념을 이해해 보겠습니다.예를 들어, 0과 1 같은 이진 값만 저장할 수 있는 배열 클래스를 만들고 싶다고 가정해 봅시다. 다음은 첫 번째 시도입니다.첫 번째 시도: 문제가 있는 코드class BinArray { int arr[10]; int & operator[](int i)
이 글에서는 C++11의 기능을 활용해 타이머를 만드는 방법을 살펴봅니다. 여기서는 later라는 이름의 클래스를 하나 작성할 것입니다. 이 클래스는 다음과 같은 속성을 가집니다.int – 코드가 실행되기까지 대기할 시간(밀리초 단위)bool – 이 값이 true이면 즉시 반환되고, 지정된 시간이 지난 후 별도의 스레드에서 코드를 실행합니다.가변 인자(variable arguments) – std::bind에 전달하고자 하는 인자들또한 chrono::milliseconds를 nanoseconds, microseconds 등으로 변경
변수의 동적 초기화란? 객체의 동적 초기화(dynamic initialization)란 객체를 프로그램 실행 시점, 즉 런타임(run time)에 초기화하는 것을 의미합니다. 다시 말해, 객체의 초깃값이 소스 코드에 미리 고정되어 있는 것이 아니라 실행 도중에 결정되어 전달됩니다. C++에서는 생성자(constructor)를 활용하여 동적 초기화를 구현할 수 있습니다. 객체를 생성할 때 생성자에 매개변수 값을 전달하면, 그 값들이 곧바로 멤버 변수의 초깃값으로 사용됩니다. 이러한 초기화 방식은 클래스 변수들을 런타임 상황에 맞게 설
C 언어에서는 freopen() 함수를 사용하여 입출력을 리디렉션할 수 있습니다. 이 함수를 활용하면 기존의 FILE 포인터를 다른 스트림으로 재지정할 수 있습니다. freopen의 기본 문법은 다음과 같습니다.FILE *freopen(const char* filename, const char* mode, FILE *stream)C++에서의 스트림 리디렉션C++ 역시 동일하게 리디렉션이 가능합니다. 다만 C++은 스트림(stream) 개념을 기반으로 작동하며, 사용자가 직접 만든 스트림뿐만 아니라 시스템 스트림도 리디렉션할 수 있다
C++에는 vector, list, set, map 등 다양한 컨테이너가 존재하며, 이러한 컨테이너의 요소들을 순회할 때는 반복자(iterator)를 활용할 수 있습니다. 하지만 C++에서 반복자를 사용할 때는 각별한 주의가 필요합니다. 컨테이너를 순회하는 도중에 컨테이너의 구조나 크기가 변경되면, 반복자가 무효화(invalidation)되어 예기치 못한 동작이나 오류가 발생할 수 있기 때문입니다. 아래 예제 코드를 통해 반복자 무효화 문제가 실제로 어떻게 발생하는지 살펴보겠습니다. 예제 코드 #include <iostream
복합(Composite) 패턴은 여러 개의 객체를 마치 하나의 객체처럼 동일한 방식으로 다루어야 할 때 사용하는 대표적인 구조적(structural) 디자인 패턴입니다. 이 패턴은 객체들을 트리(tree) 구조로 구성하여, 개별 객체(부분)와 객체들의 집합(전체)을 하나의 계층 구조로 일관성 있게 표현할 수 있게 해줍니다.복합 패턴은 자기 자신과 동일한 타입의 객체들을 담는 클래스를 생성합니다. 이 클래스는 내부에 포함된 객체 그룹을 추가하거나 삭제·수정할 수 있는 방법을 제공하며, 클라이언트는 단일 객체와 복합 객체를 구분하지 않
이번 글에서는 C++의 출력 반복자(Output Iterator)가 무엇인지, 그리고 어떤 특성을 가지는지 살펴보겠습니다. 출력 반복자는 컨테이너에 값을 쓰기 위한 특수한 목적의 반복자로, 다음과 같은 중요한 속성들을 가집니다.출력 반복자의 주요 특징출력 반복자는 컨테이너의 값을 수정(쓰기)하는 데 사용됩니다.이 반복자를 통해서는 컨테이너에서 데이터를 읽을 수 없습니다.단방향(One-Way)이며 쓰기 전용(Write-only) 반복자입니다.증가(++)는 가능하지만, 감소(--)는 할 수 없습니다.출력 반복자는 두 가지 하위 유형으로
이번 글에서는 C++의 양방향 반복자(Bidirectional Iterator)에 대해 자세히 알아보겠습니다.양방향 반복자란?양방향 반복자는 순방향 반복자(Forward Iterator)의 모든 기능을 지원하며, 여기에 전위(prefix) 및 후위(postfix) 감소 연산자(--)까지 추가로 제공합니다.이름 그대로 컨테이너의 요소를 양쪽 방향, 즉 끝을 향해(순방향)도, 시작을 향해(역방향)도 이동하며 접근할 수 있습니다.임의 접근 반복자(Random Access Iterator) 역시 양방향 반복자의 한 종류입니다.순방향 반복자
이 글에서는 방향 비순환 그래프(Directed Acyclic Graph, DAG)의 무작위 선형 확장(Random Linear Extension)을 생성하는 C++ 프로그램 작성 방법을 알아봅니다. 선형 확장이란 곧 DAG의 위상 정렬(topological sorting)을 의미하며, 하나의 그래프라도 탐색 순서에 따라 여러 가지 유효한 정렬 결과가 나올 수 있습니다. 아래와 같은 그래프를 예로 들어 살펴보겠습니다. 위상 정렬이란? 방향 비순환 그래프의 위상 정렬은 모든 정점을 한 줄로 나열한 순서를 말합니다. 핵심 조건은 간단
이 글에서는 그래프 이론에서 두 정점 사이의 최단 경로를 구하는 Johnson 알고리즘에 대해 살펴보겠습니다. 아래와 같은 그래프가 주어지면, 각 정점 쌍 사이의 최단 경로 거리를 계산할 수 있습니다. 이 프로그램은 정점의 개수, 간선의 개수, 그리고 각 간선과 그 비용을 입력으로 받아 모든 정점 간 최단 거리를 담은 거리 행렬을 출력합니다. 입력 예시 정점: 3개 간선: 5개 간선 비용: 1 2 8 2 1 12 1 3 22 3 1 6 2 3 4 출력 결과 계산된 그래프의 거리 행렬은 다음과 같습니다. 0812 1004 6
C++ 콘솔 프로그램을 실행하다 보면 결과가 화면에 출력된 직후 콘솔 창이 곧바로 닫혀버려서 실행 결과를 제대로 확인할 수 없는 경우가 종종 있습니다. 이번 글에서는 콘솔 창이 자동으로 닫히는 것을 방지하고 결과를 확인할 수 있도록 만드는 방법을 알아보겠습니다.해결 방법은 매우 간단합니다. 프로그램의 마지막에 getchar() 함수를 호출하면 됩니다. 이 함수는 키보드로부터 문자 하나가 입력될 때까지 프로그램의 실행을 대기시킵니다. 따라서 사용자가 아무 키나 누르기 전까지는 콘솔 창이 종료되지 않으므로 출력 결과를 충분히 확인할 수
C++ 기본 클래스 생성자 호출의 기본 원리 C++에서는 기존 클래스를 상속하여 새로운 파생 클래스(derived class)를 만들 수 있습니다. 파생 클래스의 객체를 생성하면 컴파일러는 먼저 슈퍼클래스, 즉 기본 클래스(base class)의 생성자를 호출한 뒤 파생 클래스의 생성자를 실행합니다. 흥미로운 점은 Java와 달리 C++에는 super처럼 슈퍼클래스를 가리키는 참조 변수나 키워드가 없다는 것입니다. 대신 다음 두 가지 규칙에 따라 기본 클래스의 생성자가 호출됩니다. 매개변수가 없는 생성자(디폴트 생성자)인 경우:
C++에서 iostream과 iostream.h의 차이점이 글에서는 C++ 프로그래밍에서 자주 혼동되는 두 헤더 파일, iostream과 iostream.h의 차이점을 자세히 살펴보겠습니다. 이름은 비슷하지만 이 둘은 서로 다른 시대와 배경에서 만들어진 파일입니다.iostream.h란?iostream.h는 1990년대 초반에 사용되던 입출력(I/O) 스트림 라이브러리의 헤더 파일입니다. AT&T에서 초기 C++ 컴파일러와 함께 사용할 목적으로 개발되었으며, 당시 C++ 언어는 아직 국제 표준으로 확정되지 않은 상태였습니다.i
예외 처리(Exception Handling)는 현대의 거의 모든 객체 지향 프로그래밍 언어에서 지원하는 핵심 기능입니다. C++와 Java 역시 예외 처리 메커니즘을 제공하며, 두 언어 모두 try-catch 블록을 사용한다는 점에서 기본적인 구조는 매우 유사합니다. 하지만 자세히 들여다보면 몇 가지 중요한 차이점이 존재합니다.1. 던질 수 있는 예외의 타입가장 큰 차이점은 예외로 던질 수 있는 데이터의 종류입니다.C++에서는 어떤 타입의 데이터든 예외로 던질 수 있습니다. 여기에는 int, char 같은 기본(primitive)
foreach 루프란?C++와 Java에는 일반적인 for 루프 외에 foreach 루프라는 또 다른 형태의 반복문이 존재합니다. C 언어에는 없는 문법으로, C++11 표준과 Java JDK 1.5.0부터 도입되었습니다.foreach 루프의 가장 큰 장점은 초기화, 조건 검사, 증감 연산 과정 없이도 배열이나 컨테이너의 요소에 매우 빠르게 접근할 수 있다는 점입니다. 따라서 하나의 배열이나 컨테이너에 담긴 모든 요소를 순차적으로 처리할 때 특히 유용합니다.참고로 이 루프는 foreach라고 불리지만, 실제 코드 작성 시에는 for
C++ 프로그래밍에서 범위 지정 연산자(scope resolution operator, ::)와 this 포인터는 모두 클래스 멤버에 접근하는 데 사용되지만, 그 용도와 동작 방식은 서로 다릅니다. 이번 글에서는 몇 가지 예제 코드를 통해 두 기능이 어떤 상황에서 어떻게 사용되는지 살펴보겠습니다.멤버 변수가 지역 변수에 가려지는 문제클래스에 멤버 변수 x가 있고, 같은 이름 x를 매개변수로 받는 함수가 있다고 가정해 봅시다. 이 경우 함수 내부에서 x를 참조하면 멤버 변수는 가려지고(shadowing), 지역 변수인 매개변수가 대신
C++ isnormal() 함수란?이번 글에서는 C++의 isnormal() 함수에 대해 자세히 알아보겠습니다. 이 함수는 <cmath> 헤더 파일에 정의되어 있으며, 주어진 부동 소수점 수가 정규 값(normal value)인지 여부를 판별하는 데 사용됩니다.정규 값이 아닌(non-normal) 숫자에는 다음과 같은 것들이 포함됩니다.0 (영)무한대(Infinity)NAN (Not a Number)isnormal() 함수의 동작 방식isnormal() 함수는 float, double, long double 타입의 값을
C++에서 클래스를 설계할 때 대입 연산자(operator=)를 직접 작성해야 하는 경우가 언제인지 알아보겠습니다. 핵심 기준은 간단합니다. 클래스 내부에 포인터 멤버 변수가 있는지 없는지에 따라 달라집니다.클래스에 포인터 멤버가 없다면 컴파일러가 자동으로 생성해 주는 기본 복사 생성자와 대입 연산자만으로 충분하기 때문에 굳이 직접 작성할 필요가 없습니다. 하지만 포인터 멤버가 존재하는 경우에는 기본 연산자가 얕은 복사(shallow copy)를 수행하면서 예기치 않은 문제를 일으킬 수 있으므로, 상황에 맞게 직접 구현해야 합니다.
C++에서 컨테이너의 요소를 무작위로 섞을 때 사용하는 대표적인 함수로 random_shuffle()과 shuffle()이 있습니다. 두 함수는 이름은 비슷하지만 내부 동작 방식과 권장 여부에 중요한 차이가 있습니다. 이번 글에서는 두 함수의 개념, 사용 예제, 그리고 핵심 차이점까지 자세히 살펴보겠습니다.random_shuffle()이란?random_shuffle()은 지정된 범위 [left, right) 내의 요소들을 무작위로 재배열하는 함수입니다. 각 요소의 위치를 임의로 선택된 다른 위치와 서로 교환(swap)하는 방식으로