STL
STL이란?
- 효율적인 데이터 구조 및 알고리즘을 제공하는 강력한 라이브러리
- 데이터 구조, 반복자, 알고리즘을 쉽게 활용할 수 있다
알고리즘(Algorithms)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {5, 2, 8, 3, 1};
sort(vec.begin(), vec.end()); // 정렬
for (int v : vec) cout << v << " "; // 1 2 3 5 8
return 0;
}
컨테이너(Container)
- 데이터를 저장하는 구조이며, 크게 순차 컨테이너, 연관 컨테이너, 컨테이너 어댑터로 나뉜다
- 다양한 데이터 구조(vector, list, map 등) 제공
반복자(Iterator)
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {10, 20, 30};
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " ";
}
return 0;
}
데이터 타입
스택(Stack)
- LIFO(Last In First Out) 구조를 가지며, push(), pop(), toop() 메서드를 사용
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
s.push(10);
s.push(20);
cout << s.top(); // 20
s.pop();
cout << s.top(); // 10
return 0;
}
큐(Queue)
- FIFO(First In First Out) 구조를 가지며, push(), pop(), front(), back() 메서드를 사용
#include <queue>
using namespace std;
queue<int> q;
q.push(1);
q.push(2);
cout << q.front(); // 1
디큐(Deque)
#include <deque>
using namespace std;
deque<int> dq;
dq.push_front(10);
dq.push_back(20);
우선순위 큐(Priority Queue)
- 최대 힙(기본값) 또는 최소 힙을 제공하는 컨테이너
#include <queue>
priority_queue<int> pq;
pq.push(3);
pq.push(5);
cout << pq.top(); // 5
맵(Map)
- Key-Value 형태의 데이터를 저장하는 연관 컨테이너
#include <map>
map<string, int> myMap;
myMap["Alice"] = 30;
cout << myMap["Alice"]; // 30
셋(Set)
#include <set>
set<int> mySet;
mySet.insert(10);
mySet.insert(20);
벡터(Vector)
- 동적 배열을 제공하며, push_back(), size() 등을 사용할 수 있다
#include <vector>
vector<int> v = {1, 2, 3};
v.push_back(4);
리스트(List)
#include <list>
list<int> myList;
myList.push_back(10);
C++11
C++11이란?
- C++의 기능을 대폭 개선한 주요 업데이트로, 타입 추론, 람다 표현식, 스마트 포인터, 가변 인자 등의 다양한 기능이 추가되었다
Auto
- 컴파일러가 변수의 타입을 자동으로 추론하도록 한다
- 타입을 명시하지 않고도 직관적인 코드를 작성할 수 있다
- 코드의 가독성이 향상되고, 유지보수가 쉬워지며, 긴 타입 이름을 자동으로 처리
#include <iostream>
#include <vector>
using namespace std;
int main() {
auto x = 10; // int
auto pi = 3.14; // double
auto name = "Alice"; // const char*
vector<int> vec = {1, 2, 3};
auto it = vec.begin(); // vector<int>::iterator
cout << *it << endl; // 1
return 0;
}
사용 목적
- 반복자와 같은 긴 타입을 간결하게 표현
- 특정 타입을 변경할 경우, 모든 변수 타입을 일일이 수정하지 않아도 된다
- 템플릿과 함께 사용하여 유연한 코드를 작성할 수 있다
decltype
- 변수나 표현식의 타입을 결정하는 데 사용
- auto와 달리 변수를 초기화하지 않고 타입을 추론할 수 있다
#include <iostream>
using namespace std;
int main() {
int x = 42;
decltype(x) y = 10; // y는 int 타입
cout << y << endl;
return 0;
}
사용 목적
- 표현식의 타입을 그대로 유지할 때 사용
- auto보다 더 정밀하게 타입을 결정할 때 사용
decltype(auto)
auto getValue() -> decltype(42) {
return 42;
}
Final
- 클래스 및 가상 함수에서 final 키워드를 사용하여 상속 또는 오버라이딩을 금지할 수 있다
class Base {
public:
virtual void show() final { // 더 이상 오버라이딩 불가능
cout << "Base class" << endl;
}
};
class Derived : public Base {
// void show() override; // 오류! 'show'는 final로 선언됨
};
class FinalClass final {}; // 상속 불가
class DerivedClass : public FinalClass {}; // 오류 발생
사용 목적
- 특정 클래스의 상속을 방지하고 싶을 때 사용
- 특정 멤버 함수의 재정의를 막고 싶을 때 사용
Lambda
#include <iostream>
using namespace std;
int main() {
auto add = [](int a, int b) { return a + b; };
cout << add(10, 20) << endl; // 30
return 0;
}
int x = 10;
auto lambda = [x]() { return x * 2; };
cout << lambda(); // 20
사용 목적
- 간단한 콜백 함수를 정의할 때
- STL 알고리즘에서 사용자 정의 함수로 활용할 때
- 함수 객체(functor) 대신 사용하여 가독성 향상
스마트 포인터(Smart Pointers)
- 메모리 누수를 방지하기 위해 unique_ptr, shared_ptr, weak_ptr이 도입되었다
unique_ptr
- 단독 소유 스마트 포인터
- 하나의 포인터만 특정 객체를 소유할 수 있는 스마트 포인터
- 다른 unique_ptr에 할당할 수 없으며, move()를 사용하여 소유권을 이동할 수 있다
#include <memory>
unique_ptr<int> ptr = make_unique<int>(10);
cout << *ptr << endl; // 10
shared_ptr
- 공동 소유 스마트 포인터
- 여러 개의 포인터가 같은 객체를 공유할 수 있는 스마트 포인터
- 참조 카운트를 유지하며, 마지막 shared_ptr이 소멸될 때 메모리를 해제한다
#include <memory>
shared_ptr<int> p1 = make_shared<int>(20);
shared_ptr<int> p2 = p1;
cout << *p2 << endl; // 20
weak_ptr
- 순환 참조 방지 스마트 포인터
- shared_ptr과 함께 사용되며, 참조 카운트 증가 없이 객체를 참조할 수 있다
- shared_ptr간의 순환 참조 문제를 방지하는데 사용된다
#include <memory>
weak_ptr<int> wptr;
In-Class Initializer & Delegation of Contructors
클래스 내 초기화(In-Class Initializer)
class MyClass {
public:
int x = 10;
};
생성자 위임(Delegation of Contructors)
class MyClass {
public:
int x;
MyClass(int a) : x(a) {}
MyClass() : MyClass(0) {} // 생성자 위임
};
가변 인자(Ellipsis)
#include <iostream>
using namespace std;
template<typename... Args>
void print(Args... args) {
(cout << ... << args) << endl;
}
int main() {
print(1, 2, 3, "Hello");
return 0;
}