C++는 강력한 기능을 가진 언어로, 고급 주제를 통해 더욱 깊이 있는 프로그래밍 기법을 익힐 수 있습니다. 여기서는 C++의 고급 주제에 대해 설명하겠습니다.
1. 스마트 포인터 (Smart Pointers)
스마트 포인터는 동적 메모리 관리를 쉽게 하고, 메모리 누수를 방지하는데 사용됩니다. C++11부터 제공되는 스마트 포인터는 다음과 같습니다:
unique_ptr: 단독 소유권을 가지는 스마트 포인터. 복사할 수 없으며, 이동만 가능합니다.
std::unique_ptr<int> p1(new int(10)); std::unique_ptr<int> p2 = std::move(p1); // p1의 소유권을 p2로 이동
shared_ptr: 참조 계수를 이용하여 메모리를 공유하는 스마트 포인터. 여러 개의shared_ptr이 동일한 객체를 가리킬 수 있습니다.
std::shared_ptr<int> p1(new int(20)); std::shared_ptr<int> p2 = p1; // p1과 p2가 동일한 객체를 가리킴
weak_ptr: 순환 참조 문제를 해결하기 위해 사용되는 스마트 포인터.shared_ptr와 함께 사용되며, 객체의 소유권을 가지지 않습니다.
std::shared_ptr<int> sp(new int(30)); std::weak_ptr<int> wp = sp; // wp는 sp가 가리키는 객체를 약하게 참조
2. 동시성 (Concurrency) 및 멀티스레딩 (Multithreading)
C++11부터 표준 라이브러리에 멀티스레딩을 지원하는 기능이 포함되었습니다.
std::thread: 새로운 스레드를 생성하여 병렬로 작업을 수행할 수 있습니다.
void threadFunction() {
std::cout << "Thread is running\n";
}
int main() {
std::thread t(threadFunction);
t.join(); // 메인 스레드가 t 스레드의 종료를 기다림
return 0;
}
std::mutex: 상호 배제를 통해 여러 스레드가 공유 자원에 동시에 접근하지 못하게 합니다.
std::mutex mtx;
void printFunction(const std::string& msg) {
std::lock_guard<std::mutex> guard(mtx);
std::cout << msg << std::endl;
}
std::async및std::future: 비동기 작업을 수행하고 그 결과를 나중에 얻을 수 있습니다.
std::future<int> result = std::async([](int a, int b) { return a + b; }, 2, 3);
std::cout << "Result: " << result.get() << std::endl; // 결과를 기다림
3. 람다 표현식 (Lambda Expressions)
람다 표현식은 익명 함수를 정의하는 문법으로, 간단한 콜백 함수나 일회용 함수를 작성할 때 유용합니다.
- 기본 사용법:
auto add = [](int a, int b) { return a + b; };
std::cout << "Sum: " << add(2, 3) << std::endl;
- 캡처 리스트를 이용한 외부 변수 접근:
int x = 10;
auto increment = [&x]() { x++; };
increment();
std::cout << "x: " << x << std::endl; // x는 11이 됨
4. 이동 시맨틱 (Move Semantics)
이동 시맨틱은 자원의 불필요한 복사를 피하고 성능을 최적화하는 데 사용됩니다. C++11부터 이동 생성자와 이동 대입 연산자가 도입되었습니다.
- 이동 생성자와 이동 대입 연산자:
class MoveExample {
public:
int* data;
MoveExample(int size) : data(new int[size]) {}
// 이동 생성자
MoveExample(MoveExample&& other) noexcept : data(other.data) {
other.data = nullptr;
}
// 이동 대입 연산자
MoveExample& operator=(MoveExample&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
other.data = nullptr;
}
return *this;
}
~MoveExample() { delete[] data; }
};
std::move를 이용한 이동:
MoveExample createExample(int size) {
MoveExample example(size);
return example;
}
int main() {
MoveExample ex = createExample(5);
MoveExample ex2 = std::move(ex); // ex의 자원을 ex2로 이동
return 0;
}
5. 정규 표현식 (Regular Expressions)
C++11부터 표준 라이브러리에 정규 표현식 기능이 포함되었습니다.
std::regex를 이용한 정규 표현식 매칭:
std::regex pattern("\\d+");
std::string text = "The year is 2023.";
if (std::regex_search(text, pattern)) {
std::cout << "Number found!" << std::endl;
}
- 정규 표현식을 이용한 문자열 치환:
std::regex pattern("year");
std::string text = "The year is 2023.";
std::string replaced = std::regex_replace(text, pattern, "month");
std::cout << replaced << std::endl; // "The month is 2023."
6. 메타프로그래밍 (Template Metaprogramming)
메타프로그래밍은 컴파일 타임에 코드를 생성하는 기법으로, 주로 템플릿을 이용합니다.
- 템플릿 재귀를 이용한 팩토리얼 계산:
template<int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};
template<>
struct Factorial<0> {
static const int value = 1;
};
std::cout << "Factorial of 5: " << Factorial<5>::value << std::endl; // 120
std::enable_if를 이용한 SFINAE (Substitution Failure Is Not An Error):
template<typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
isEven(T num) {
return num % 2 == 0;
}
std::cout << std::boolalpha << isEven(4) << std::endl; // true
C++의 고급 주제는 매우 넓고 깊은 내용을 포함하고 있습니다. 이 목차를 따라가며 각 주제를 깊이 있게 공부하면 C++ 프로그래밍의 고급 기술을 익히고 활용할 수 있게 될 것입니다.
