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++ 프로그래밍의 고급 기술을 익히고 활용할 수 있게 될 것입니다.