C++ 학습: 고급 주제
C++는 다양한 고급 기능을 통해 복잡한 프로그램을 효율적으로 작성할 수 있도록 합니다. 이번 글에서는 전처리기 지시자, 네임스페이스, 다중 스레딩, 그리고 최신 C++ 표준의 새로운 기능들에 대해 알아보겠습니다.
1. 전처리기 지시자: #define, #include, #if 등
전처리기 지시자는 컴파일러가 소스 코드를 컴파일하기 전에 처리해야 할 명령을 지정합니다. 주요 전처리기 지시자는 다음과 같습니다.
- #define : 매크로를 정의합니다.
#define SQUARE(x) ((x) * (x))
#include <iostream>
using namespace std;
int main() {
cout << "PI: " << PI << endl;
cout << "SQUARE(5): " << SQUARE(5) << endl;
return 0;
}
- #include : 다른 파일을 포함합니다.
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
for (int i : vec) {
cout << i << " ";
}
cout << endl;
return 0;
}
- #if, #elif, #else, #endif : 조건부 컴파일을 수행합니다.
using namespace std;
#define DEBUG
int main() {
#ifdef DEBUG
cout << "Debug mode is ON" << endl;
#else
cout << "Debug mode is OFF" << endl;
#endif
return 0;
}
위의 예제에서 #define은 상수와 매크로를 정의하고, #include는 필요한 헤더 파일을 포함하며, #if 계열의 지시자는 조건부로 코드를 컴파일할 수 있도록 합니다.
2. 네임스페이스: 네임스페이스의 정의와 사용
네임스페이스는 이름 충돌을 방지하고 코드의 가독성을 높이기 위해 사용됩니다. 네임스페이스를 정의하고 사용하는 방법은 다음과 같습니다.
- 네임스페이스 정의와 사용 예제
namespace MyNamespace {
void myFunction() {
std::cout << "Hello from MyNamespace!" << std::endl;
}
}
int main() {
MyNamespace::myFunction(); // 네임스페이스를 사용하여 함수 호출
return 0;
}
위의 예제에서 MyNamespace 네임스페이스는 myFunction 함수를 정의하고, main 함수에서 이를 호출합니다.
- 네임스페이스를 사용하여 이름 충돌 방지
namespace FirstNamespace {
void display() {
std::cout << "This is FirstNamespace" << std::endl;
}
}
namespace SecondNamespace {
void display() {
std::cout << "This is SecondNamespace" << std::endl;
}
}
int main() {
FirstNamespace::display(); // FirstNamespace의 display 함수 호출
SecondNamespace::display(); // SecondNamespace의 display 함수 호출
return 0;
}
위의 예제에서 두 개의 네임스페이스 FirstNamespace와 SecondNamespace는 각각 display 함수를 정의하고, 이름 충돌 없이 독립적으로 사용할 수 있습니다.
3. 다중 스레딩: C++11의 std::thread
다중 스레딩은 여러 스레드를 사용하여 동시에 여러 작업을 수행하는 기능입니다. C++11에서는 std::thread를 통해 다중 스레딩을 지원합니다.
- 다중 스레딩 예제
#include <thread>
void printHello() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t1(printHello); // 스레드 생성
t1.join(); // 스레드가 종료될 때까지 대기
std::thread t2([]() {
std::cout << "Hello from lambda thread!" << std::endl;
});
t2.join();
return 0;
}
위의 예제에서 std::thread를 사용하여 두 개의 스레드를 생성하고, 각각의 스레드에서 함수를 실행합니다. join 함수를 사용하여 스레드가 종료될 때까지 대기합니다.
- 다중 스레딩에서 데이터 공유
#include <thread>
#include <vector>
void accumulateSum(int& sum, const std::vector<int>& nums) {
for (int num : nums) {
sum += num;
}
}
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5};
int sum = 0;
std::thread t(accumulateSum, std::ref(sum), std::ref(nums)); // 스레드 생성
t.join(); // 스레드가 종료될 때까지 대기
std::cout << "Sum: " << sum << std::endl;
return 0;
}
위의 예제에서 std::ref를 사용하여 sum 변수와 nums 벡터를 스레드 함수에 참조로 전달합니다.
4. C++11, C++14, C++17, C++20의 새로운 기능: 최신 C++ 표준의 새로운 기능들
C++의 최신 표준(C++11, C++14, C++17, C++20)은 다양한 새로운 기능을 도입하여 언어의 표현력과 성능을 향상시켰습니다. 주요 기능들은 다음과 같습니다:
1. C++11
- 자동 타입 추론(auto)
auto y = 3.14; // y는 double 타입
- 범위 기반 for 루프
#include <iostream>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
for (auto i : vec) {
cout << i << " ";
}
cout << endl;
return 0;
}
- 스마트 포인터(unique_ptr, shared_ptr)
#include <iostream>
using namespace std;
int main() {
unique_ptr<int> ptr1 = make_unique<int>(10);
cout << *ptr1 << endl;
shared_ptr<int> ptr2 = make_shared<int>(20);
cout << *ptr2 << endl;
return 0;
}
2. C++14
- 제네릭 람다
cout << lambda(2, 3) << endl; // 5
cout << lambda(2.5, 3.5) << endl; // 6.0
3. C++17
- 구조화된 바인딩
#include <iostream>
using namespace std;
int main() {
tuple<int, double, string> t(1, 2.3, "tuple");
auto [a, b, c] = t;
cout << a << " " << b << " " << c << endl;
return 0;
}
- if 초기화문
using namespace std;
int main() {
if (int x = 10; x > 5) {
cout << "x is greater than 5" << endl;
}
return 0;
}
4. C++20
- 코루틴
#include <coroutine>
struct ReturnObject {
struct promise_type {
ReturnObject get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
};
};
ReturnObject counter() {
for (int i = 0; i < 3; ++i) {
std::cout << i << std::endl;
co_await std::suspend_always{};
}
}
int main() {
auto h = counter();
return 0;
}
- 개념(concepts)
#include <concepts>
template <typename T>
concept Integral = std::is_integral_v<T>;
template <Integral T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << add(2, 3) << std::endl;
// std::cout << add(2.0, 3.0) << std::endl; // 오류: double은 Integral이 아님
return 0;
}
위의 예제들은 최신 C++ 표준의 주요 기능들을 보여줍니다. 이러한 기능들은 코드의 표현력을 높이고, 더 안전하고 효율적인 프로그램을 작성하는 데 도움을 줍니다.
이번 글에서는 C++의 고급 주제에 대해 알아보았습니다. 전처리기 지시자, 네임스페이스, 다중 스레딩, 그리고 최신 C++ 표준의 새로운 기능들을 이해하고 활용하면 복잡한 프로그램을 더 효율적으로 작성할 수 있습니다. 다음 단계에서는 실습과 프로젝트를 통해 이러한 기능들을 실제로 적용해보세요. Happy Coding!
'프로그래밍 > C++' 카테고리의 다른 글
[C++] 12. C++의 "프로젝트 및 실습(기타)" (0) | 2024.06.17 |
---|---|
[C++] 10. C++의 "예외 처리" (1) | 2024.06.17 |
[C++] 9. C++의 "파일 입출력" (0) | 2024.06.17 |
[C++] 8. C++의 "표준 템플릿 라이브러리 (STL)" (0) | 2024.06.17 |
[C++] 7. C++의 "객체 지향 프로그래밍" (0) | 2024.06.17 |