liminfo

C++ Reference

C++ 프로그래밍 레퍼런스

44개 결과

C++ Reference 소개

C++ 레퍼런스는 기초 문법부터 고급 언어 기능까지 현대 C++을 포괄적으로 정리한 검색 가능한 치트 시트입니다. 기본문법 섹션에서는 auto를 이용한 타입 추론(C++11), constexpr을 이용한 컴파일 타임 계산, 범위 기반 for문, enum class를 이용한 스코프 열거형, 네임스페이스, C++17 초기화 구문을 포함한 if문(if (auto it = m.find(key); it != m.end()))을 다룹니다. 포인터 섹션에서는 원시 포인터 산술, 참조 시맨틱스, new/delete를 이용한 동적 메모리 할당, null 포인터 리터럴 nullptr(C++11), static_cast를 이용한 void* 타입 변환을 다룹니다. 클래스 섹션에서는 접근 지정자, 멤버 초기화 목록, override를 이용한 가상 함수, 순수 가상 인터페이스, 연산자 오버로딩, friend 선언, 복사/이동 생성자를 포함한 5의 법칙까지 객체지향 C++를 다룹니다.

템플릿 섹션에서는 C++ 제네릭 프로그래밍을 다룹니다: 함수 템플릿, Stack<T> 같은 자료구조를 위한 클래스 템플릿, 타입별 동작을 위한 템플릿 특수화, fold 표현식을 이용한 파라미터 팩 확장을 포함한 가변 템플릿, 타입 제약을 위한 C++20 Concepts(template<Numeric T>). STL 섹션에서는 가장 많이 사용되는 컨테이너를 다룹니다: push_back/emplace_back/erase를 포함한 std::vector, 구조적 바인딩을 이용한 range-for가 가능한 정렬/비정렬 std::map, insert/count/erase를 포함한 std::set, substr/find/replace를 포함한 std::string, 알고리즘 헤더(sort/reverse/find/count), 캡처 목록을 가진 람다 표현식, C++17 구조적 바인딩(auto [a, b, c] = t)을 포함한 std::pair/tuple.

스마트포인터 섹션에서는 원시 new/delete를 없애는 RAII 기반 메모리 관리 도구를 다룹니다: 단독 소유권을 위한 std::unique_ptr(make_unique, 이동 전용 시맨틱스), 참조 카운팅 공유 소유권을 위한 std::shared_ptr(make_shared, use_count), 순환 참조를 끊기 위한 std::weak_ptr(weak.lock()). 동시성 섹션에서는 std::thread 생성과 join(), 데이터 경쟁 방지를 위한 lock_guard를 이용한 std::mutex, 비차단 작업 실행을 위한 std::async와 std::future, 락프리 연산을 위한 std::atomic을 다룹니다. 모던 C++ 섹션에서는 C++17/20 기능을 다룹니다: std::optional, std::visit를 이용한 std::variant, 구조적 바인딩, std::string_view, 컴파일 타임 분기를 위한 if constexpr, 뷰 파이프라인을 이용한 C++20 ranges 라이브러리.

주요 기능

  • auto 타입 추론, constexpr 컴파일 타임 계산, 범위 기반 for문 (C++11)
  • virtual/override, 순수 가상 인터페이스, 연산자 오버로딩, 이동 시맨틱스를 포함한 클래스 정의
  • 함수/클래스 템플릿, 템플릿 특수화, 가변 템플릿, C++20 Concepts
  • STL 컨테이너: vector, map/unordered_map, set, string, 알고리즘 라이브러리
  • STL 알고리즘 콜백을 위한 캡처 목록([factor], [&], [=])을 가진 람다 표현식
  • 스마트포인터: unique_ptr(단독), shared_ptr(참조 카운팅), weak_ptr(순환 참조 방지)
  • 동시성: std::thread, lock_guard를 이용한 std::mutex, std::async/future, std::atomic
  • 모던 C++17/20: optional, variant/visit, 구조적 바인딩, string_view, if constexpr, ranges

자주 묻는 질문

unique_ptr과 shared_ptr의 차이는 무엇인가요?

std::unique_ptr은 단독 소유권을 나타냅니다. 한 번에 하나의 unique_ptr만 객체를 가리킬 수 있고 복사할 수 없으며(이동만 가능) unique_ptr이 스코프를 벗어나면 객체가 소멸됩니다. std::shared_ptr은 참조 카운팅을 사용해 여러 소유자를 허용합니다. 마지막 shared_ptr이 소멸되거나 reset될 때 객체가 소멸됩니다. unique_ptr은 원시 포인터와 오버헤드가 동일하고, shared_ptr은 제어 블록으로 인한 작은 오버헤드가 있습니다. 기본적으로 unique_ptr을 사용하고, 진정한 공유 소유권이 필요할 때만 shared_ptr을 사용합니다.

std::weak_ptr은 어떤 문제를 해결하나요?

std::weak_ptr은 shared_ptr의 순환 참조 문제를 해결합니다. 두 객체가 서로를 가리키는 shared_ptr을 보유하면 참조 카운트가 0에 도달하지 않아 메모리 누수가 발생합니다. weak_ptr은 참조 카운트를 증가시키지 않는 비소유 참조입니다. 객체를 사용하려면 weak.lock()을 호출해 객체가 살아있으면 shared_ptr을, 소멸되었으면 nullptr을 반환받습니다. 부모-자식 관계에서 부모가 자식의 shared_ptr을 보유하고 자식이 부모를 weak_ptr로 가리키는 패턴이 일반적입니다.

const와 constexpr의 차이는 무엇인가요?

const는 변수나 멤버 함수가 런타임에 읽기 전용임을 선언합니다. 값은 런타임에 계산되어 한 번 할당될 수 있습니다. constexpr은 변수나 함수가 컴파일 타임에 평가 가능해야 함을 선언합니다. constexpr 변수는 암묵적으로 const입니다. constexpr 함수는 컴파일 타임 인수가 주어지면 컴파일 타임 상수를 생성하고, 그렇지 않으면 일반 함수처럼 런타임에 실행됩니다. 배열 크기나 템플릿 인수처럼 컴파일 타임에 확정되는 값에는 constexpr을 사용해 컴파일러 최적화를 활용하세요.

람다는 언제 이름 있는 함수 대신 사용해야 하나요?

람다는 한 곳에서만 사용되는 짧고 문맥에 특화된 연산에 가장 적합합니다. 특히 STL 알고리즘(std::sort, std::find_if, std::transform)의 콜백으로 유용합니다. 캡처 목록 []을 이용해 지역 변수를 참조할 수 있습니다: [&]은 참조로 모두 캡처, [=]은 값으로 모두 캡처, [factor]는 named 변수만 값으로 캡처합니다. 여러 곳에서 재사용되는 복잡한 연산에는 이름 있는 함수나 함수자가 더 명확합니다.

이동 시맨틱스란 무엇이고 성능에 왜 중요한가요?

이동 시맨틱스(C++11)는 복사 대신 객체의 내부 리소스(힙 할당 버퍼 등)를 새 객체로 전송하는 것을 허용합니다. 원본 객체는 유효하지만 명세되지 않은 상태로 남습니다. 이는 함수에서 큰 객체를 반환하거나 컨테이너에 삽입할 때 비용이 큰 깊은 복사를 제거합니다. 이동 생성자는 rvalue 참조(&&)로 호출됩니다. std::move()는 lvalue를 rvalue로 캐스팅해 이동을 명시적으로 요청합니다. std::vector, std::string, 모든 STL 컨테이너가 이동 시맨틱스를 구현합니다.

std::map과 std::unordered_map의 차이는?

std::map은 레드-블랙 트리로 키를 정렬된 순서로 유지합니다. 검색, 삽입, 삭제가 O(log n)입니다. std::unordered_map은 해시 테이블로 동일 연산의 평균 복잡도가 O(1)입니다. 정렬된 키가 필요하거나(lower_bound를 이용한 범위 쿼리), 키에 해시 함수가 없거나, 최악의 경우 O(n) 해시 충돌보다 O(log n)이 나을 때는 std::map을 사용합니다. 정렬이 필요 없는 고성능 검색에는 std::unordered_map을 사용합니다.

C++20 Concepts란 무엇이고 템플릿 오류 메시지를 어떻게 개선하나요?

C++20 Concepts는 템플릿 타입 파라미터를 제약하는 명명된 컴파일 타임 조건입니다. 예: template<typename T> concept Numeric = std::is_arithmetic_v<T>;는 산술 타입만 허용하는 Concept을 정의합니다. template<typename T> 대신 template<Numeric T>를 사용하면 코드에서 제약이 명시적으로 보이고, 타입이 Concept을 만족하지 않으면 컴파일러가 호출 지점에서 명확한 오류를 발생시킵니다. 비제약 템플릿의 악명 높은 치환 실패 오류 대신 이해하기 쉬운 메시지를 받을 수 있습니다.

구조적 바인딩(Structured Bindings)이란 무엇이고 언제 사용하나요?

구조적 바인딩(C++17)은 구조체, std::pair, std::tuple, 배열을 단일 선언으로 명명된 변수에 분해합니다: auto [key, val] = *map.begin(). 맵의 range-for 루프(for (const auto& [k, v] : m))와 tuple이나 구조체로 여러 값을 반환할 때 가장 유용합니다. std::get<0>(t) / pair.first / pair.second 같은 장황한 코드를 대체합니다. auto로 선언하면 복사, auto&로 선언하면 참조로 바인딩됩니다.