1. 메모리 구조 (Memory Layout)
프로그램이 실행될 때 메모리는 크게 네 영역으로 나뉩니다.
Code (Text) 영역: 실행할 프로그램의 명령어(기계어)가 저장되는 읽기 전용 영역.
Data 영역: 전역 변수(Global)와 정적 변수(Static)가 저장됨. 프로그램 시작 시 할당, 종료 시 해제.
Stack 영역: 함수 호출 시 생성되는 지역 변수와 매개 변수. 자동으로 관리되며 LIFO(Last-In-First-Out) 구조.
Heap 영역:
new나malloc으로 할당하는 동적 메모리. 사용자가 직접 해제해야 함 (delete/free). 해제하지 않으면 메모리 누수 발생.
2. 포인터(Pointer) vs 참조자(Reference)
포인터 (
int* ptr)* 주소값을 저장하는 변수.nullptr가능, 가리키는 대상 변경 가능.참조자 (
int& ref): 변수의 별명. 선언 시 반드시 초기화 필수,nullptr불가능, 대상 변경 불가능.
3. 객체 지향 프로그래밍 (OOP) 핵심
캡슐화: 데이터와 기능을 하나로 묶고 접근 제어(
public,private)로 보호.상속: 부모 클래스의 특성을 물려받아 재사용.
다형성: 같은 인터페이스로 서로 다른 동작을 수행 (오버로딩, 오버라이딩).
추상화: 복잡한 내부 로직을 숨기고 필요한 인터페이스만 노출.
4. 오버로딩 vs 오버라이딩
오버로딩 (Overloading): 같은 함수 이름, 다른 매개변수 (컴파일 타임).
오버라이딩 (Overriding): 상속 관계에서 부모 함수를 자식이 재정의 (런타임,
virtual필요).
5. 가상 함수 테이블 (Virtual Function Table, V-Table)
정의: 가상 함수를 가진 클래스마다 하나씩 생성되는 함수 주소 배열.
vptr: 각 객체가 가지고 있는 숨겨진 포인터로, 소속 클래스의 V-Table을 가리킴.
동작: 부모 포인터로 함수 호출 시, 객체의
vptr을 통해 V-Table에 접속하여 실제 오버라이딩된 함수의 주소를 찾아 실행함 (동적 바인딩).
6. 가상 소멸자 (Virtual Destructor)
상속 관계에서 부모 클래스 포인터로 자식 객체를
delete할 때, 자식 클래스의 소멸자가 호출되지 않는 문제를 방지하기 위해 부모 소멸자에virtual을 반드시 붙여야 함.
7. 캐스팅 (Casting)
static_cast: 일반적인 타입 변환 (논리적으로 연관 있는 타입).dynamic_cast: 상속 관계의 안전한 다운 캐스팅 (런타임에 타입 체크, RTTI 필요).const_cast:const성질을 제거할 때 사용.
8. STL 컨테이너 시간 복잡도
vector: 임의 접근 $O(1)$, 끝부분 삽입/삭제 $O(1)$, 중간 삽입/삭제 $O(N)$.list: 임의 접근 $O(N)$, 삽입/삭제 $O(1)$.map/set: 이진 탐색 트리 기반, 정렬됨. 탐색/삽입 $O(\log N)$.unordered_map: 해시 테이블 기반. 탐색/삽입 평균 $O(1)$.
9. 주요 키워드
const: 값의 변경을 막음.const int* p: 데이터가 상수.int* const p: 포인터가 상수.
static:지역 변수: 함수가 끝나도 값 유지.
멤버 변수: 객체 간 공유되는 클래스 변수.
inline: 함수 호출 오버헤드를 줄이기 위해 코드 본문을 직접 삽입하도록 컴파일러에 권장.
10. 스마트 포인터 (Smart Pointers - <memory>)
자원 누수를 방지하기 위해 메모리를 자동으로 관리하는 객체.
unique_ptr: 특정 객체의 소유권을 독점함. 복사 불가능,std::move를 통한 이동만 가능.shared_ptr: 참조 횟수(Reference Count)를 기반으로 소유권을 공유. 참조 횟수가 0이 되면 메모리 해제.weak_ptr:shared_ptr의 순환 참조(Circular Reference) 문제를 해결하기 위해 사용. 소유권을 갖지 않고 객체 존재 여부만 확인.
11. R-value 참조와 이동 생성자 (Move Semantics)
불필요한 깊은 복사(Deep Copy)를 방지하여 성능을 최적화함.
L-value: 이름이 있고 주소를 취할 수 있는 변수.
R-value: 임시 객체와 같이 곧 사라지는 값.
std::move: L-value를 R-value로 캐스팅하여 이동 생성자가 호출되도록 유도. 자원을 복사하는 대신 '탈취'함.
12. RAII (Resource Acquisition Is Initialization)
개념: 자원 획득은 초기화와 동시에 이루어져야 하며, 자원의 수명은 객체의 수명과 일치해야 함.
응용: 스마트 포인터,
std::lock_guard등이 대표적임. 생성자에서 자원을 할당받고 소멸자에서 해제하여 예외 상황에서도 자원 누수를 방지.
13. 람다 캡처 (Lambda Capture)
함수 객체를 익명으로 생성할 때 외부 변수를 사용하는 방식.
[ ]: 캡처 없음.[=]: 외부의 모든 변수를 값으로 복사하여 사용 (읽기 전용).[&]: 외부의 모든 변수를 참조로 사용 (원본 수정 가능).[x, &y]: x는 값으로, y는 참조로 선택적 캡처.
14. 복사 생성자 vs 대입 연산자 (Rule of Three/Five)
클래스가 동적 할당 자원을 관리할 때 정의해야 하는 멤버들.
소멸자 (Destructor)
복사 생성자 (Copy Constructor)
복사 대입 연산자 (Copy Assignment Operator)
(C++11 추가) 이동 생성자 (Move Constructor)
(C++11 추가) 이동 대입 연산자 (Move Assignment Operator)
15. 가상 상속 (Virtual Inheritance) - 다이아몬드 문제
문제 상황: 클래스 B와 C가 A를 상속받고, D가 B와 C를 동시에 상속받을 때 A의 멤버가 중복 생성되는 문제.
해결:
class B : virtual public A형태로 상속받으면, 최하위 자식 객체 내에 부모 클래스(A)의 인스턴스가 단 하나만 존재하도록 보장함.
16. 완벽한 전달 (Perfect Forwarding)
개념: 전달받은 인수의 L-value/R-value 속성을 그대로 유지하며 다른 함수로 전달하는 기술.
핵심: 템플릿의 보편적 참조(Universal Reference)
T&&와std::forward<T>()를 조합하여 사용.
17. SFINAE 및 enable_if (Template Metaprogramming)
SFINAE: "Substitution Failure Is Not An Error" (치환 실패는 에러가 아니다). 템플릿 인자 치환에 실패해도 다른 오버로딩 후보를 계속 찾는 성질.
std::enable_if: 특정 조건(예: 정수 타입일 때만)에 따라 템플릿 함수를 활성화하거나 비활성화할 때 사용.CPP 20 에서는
enable_if가 아닌 'require' 로 사용함
18. CRTP (Curiously Recurring Template Pattern)
개념: 자식 클래스가 자신의 이름을 부모 클래스의 템플릿 인자로 넘겨 상속받는 패턴.
목적: 가상 함수 테이블(V-Table)을 거치지 않는 정적 다형성을 구현하여 실행 시간 성능을 최적화함.
template <typename T> class Base { ... }; class Derived : public Base<Derived> { ... }; ex) static_cast<T*>(this)->자식함수이름();
19. 예외 안정성 (Exception Safety)
기본 보장 (Basic): 예외 발생 시 자원 누수는 없으나 객체의 상태를 예측할 수 없음.
강력한 보장 (Strong): 예외 발생 시 호출 전 상태로 완벽히 복구 (Rollback). 보통
copy-and-swap기법 사용.예외 불가 보장 (No-throw): 절대 예외를 던지지 않음 (
noexcept키워드).
20. 메모리 정렬 및 패딩 (Memory Alignment & Padding)
성능 최적화를 위해 CPU가 데이터를 읽기 좋은 단위(4/8바이트 등)로 정렬함.
이로 인해 구조체 내부 멤버 사이에 빈 공간(Padding)이 생길 수 있으며, 멤버 선언 순서에 따라
sizeof(struct)결과가 달라질 수 있음.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.