함수 포인터와 함수 객체
2025. 3. 27. 23:43ㆍProgramming Languages/C++
4.2 함수 포인터와 함수 객체
4.2.1 함수 포인터(Function Pointers)
함수의 주소를 저장하고 호출하는 방법입니다:
#include <iostream>
// 함수 정의
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main() {
// 함수 포인터 선언
int (*operation)(int, int);
// 함수 포인터에 함수 할당
operation = add;
std::cout << "덧셈 결과: " << operation(5, 3) << std::endl; // 8
// 다른 함수 할당
operation = subtract;
std::cout << "뺄셈 결과: " << operation(5, 3) << std::endl; // 2
return 0;
}
typedef와 using을 활용한 가독성 향상:
#include <iostream>
// 함수 포인터 타입 정의
typedef int (*Operation)(int, int);
// 또는 C++11 이후: using Operation = int(*)(int, int);
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }
// 함수 포인터를 매개변수로 받는 함수
int calculate(int x, int y, Operation op) {
return op(x, y);
}
int main() {
int a = 10, b = 5;
std::cout << "덧셈: " << calculate(a, b, add) << std::endl;
std::cout << "뺄셈: " << calculate(a, b, subtract) << std::endl;
std::cout << "곱셈: " << calculate(a, b, multiply) << std::endl;
std::cout << "나눗셈: " << calculate(a, b, divide) << std::endl;
return 0;
}
4.2.2 람다 함수(Lambda Functions) (C++11)
익명 함수를 생성하는 간결한 방법입니다:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 5, 3, 4, 2};
// 람다 함수로 정렬 비교 함수 정의
std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
return a > b; // 내림차순 정렬
});
// 결과 출력
std::cout << "정렬된 벡터: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 람다 함수 저장 및 재사용
auto multiplyBy2 = [](int x) { return x * 2; };
std::cout << "5 × 2 = " << multiplyBy2(5) << std::endl;
return 0;
}
람다 함수의 구조:
[캡처](매개변수) -> 반환타입 { 함수본문 }
- 캡처(Capture): 외부 변수를 람다 함수 내부에서 사용하는 방법
- 매개변수(Parameters): 일반 함수와 동일한 매개변수 목록
- 반환타입(Return Type): 생략 가능 (자동 추론)
- 함수본문(Function Body): 실행할 코드
캡처 방식 예제:
#include <iostream>
int main() {
int x = 10;
int y = 20;
// 값으로 캡처
auto valueCapture = [x]() {
// x = 15; // 오류: 값으로 캡처한 변수는 수정 불가
std::cout << "x = " << x << std::endl;
};
// 참조로 캡처
auto refCapture = [&y]() {
y = 25; // 참조로 캡처한 변수는 수정 가능
std::cout << "y = " << y << std::endl;
};
// 모든 변수를 값으로 캡처
auto captureAll = [=]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
};
// 모든 변수를 참조로 캡처
auto captureAllByRef = [&]() {
x = 30;
y = 40;
std::cout << "x = " << x << ", y = " << y << std::endl;
};
// 혼합 캡처
auto mixedCapture = [=, &y]() {
// x = 50; // 오류: x는 값으로 캡처
y = 50; // y는 참조로 캡처하여 수정 가능
std::cout << "x = " << x << ", y = " << y << std::endl;
};
valueCapture();
refCapture();
captureAll();
captureAllByRef();
mixedCapture();
std::cout << "최종 x = " << x << ", y = " << y << std::endl;
return 0;
}
4.2.3 함수 객체(Function Objects)
함수처럼 동작하는 객체입니다:
#include <iostream>
#include <vector>
#include <algorithm>
// 함수 객체(Functor) 정의
class Multiplier {
private:
int factor;
public:
Multiplier(int f) : factor(f) {}
int operator()(int x) const {
return x * factor;
}
};
int main() {
Multiplier multiplyBy3(3);
std::cout << "7 × 3 = " << multiplyBy3(7) << std::endl; // 함수처럼 호출
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::vector<int> result(numbers.size());
// transform 알고리즘과 함께 사용
std::transform(numbers.begin(), numbers.end(), result.begin(), Multiplier(2));
std::cout << "각 요소를 2배로: ";
for (int num : result) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
'Programming Languages > C++' 카테고리의 다른 글
함수 고급 주제 (0) | 2025.03.27 |
---|---|
재귀(Recursion) (0) | 2025.03.27 |
함수와 재귀 (0) | 2025.03.27 |
챕터3. 실습문제 (0) | 2025.03.27 |
조건부 컴파일 (0) | 2025.03.27 |