C++ 함수 포인터의 핵심 개념과 활용

함수 포인터의 핵심 개념

함수 포인터는 C++ 언어의 핵심 기능 중 하나로, 런타임에 함수 호출의 유연성을 제공합니다. 메모리 내 함수의 시작 주소를 저장하는 포인터 변수로, 간접적인 함수 호출이 가능하게 합니다.

기본 원리

  • 함수 포인터는 실행 코드의 메모리 주소를 저장
  • 함수 시그니처(반환형, 매개변수)와 정확히 일치해야 함
  • 간접 호출을 통해 다양한 실행 경로를 동적으로 구성 가능

함수 포인터 vs 포인터 반환 함수

구분함수 포인터포인터 반환 함수
기본 형태함수 주소 저장메모리 주소 반환
선언 예시int (*funcPtr)(int)int* getData()

실전 활용 기법

기본 사용법


// 함수 타입 정의
using CalcFunc = int (*)(int, int);

// 타깃 함수 정의
int multiply(int a, int b) { return a * b; }

// 포인터 할당 및 호출
CalcFunc operation = multiply;
int result = operation(3, 4);  // 12 반환

복합 활용


// 함수 포인터 배열
CalcFunc operations[] = {
    [](int a, int b) { return a + b; },  // 람다식도 가능
    multiply,
    [](int a, int b) { return a - b; }
};

// 다양한 연산 실행
for (auto func : operations) {
    std::cout << func(10, 5) << " ";
}
// 출력: 15 50 5

고급 패턴 구현

콜백 메커니즘


// 콜백 함수 타입 정의
using Callback = void (*)(int, void*);

// 이벤트 처리기
void processEvent(Callback callback, void* data) {
    // 데이터 처리 로직
    callback(42, data);
}

// 실제 콜백 구현
void logHandler(int code, void* context) {
    std::cout << "Error code: " << code << ", Context: " 
              << static_cast(context) << std::endl;
}

int main() {
    char context[] = "System Error";
    processEvent(logHandler, context);
    return 0;
}

전략 패턴 구현


// 정렬 전략 타입
using SortStrategy = bool (*)(int, int);

// 다양한 정렬 구현
bool customSort(int a, int b) {
    return (a % 2) == (b % 2) ? a < b : (a % 2) == 1;
}

void sortArray(int arr[], int size, SortStrategy strategy) {
    // 버블 정렬 구현
    for (int i = 0; i < size-1; i++) {
        for (int j = 0; j < size-i-1; j++) {
            if (!strategy(arr[j], arr[j+1])) {
                std::swap(arr[j], arr[j+1]);
            }
        }
    }
}

int main() {
    int data[] = {3, 8, 1, 6, 2, 9};
    sortArray(data, 6, customSort);
    return 0;
}

현대 C++ 대안

std::function 활용


#include <functional>
#include <vector>

using Operation = std::function;

class MathEngine {
public:
    static int power(int a, int b) {
        return std::pow(a, b);
    }
};

int main() {
    std::vector<Operation> operations = {
        [](int x, int y) { return x + y; },
        MathEngine::power,
        std::plus<>()
    };

    for (auto op : operations) {
        std::cout << op(2, 3) << " ";
    }
    // 출력: 5 8 5
    return 0;
}

실무 팁

  • 타입 별칭(using/typedef) 사용으로 가독성 향상
  • nullptr 검증을 통한 안전한 호출
  • 멤버 함수 포인터 사용 시 클래스 컨텍스트 고려
  • 현대 C++에서는 std::function과 람다 우선 적용

주요 오류 사례


// 잘못된 타입 매칭
float (*wrongFunc)(double) = sqrt;  // 컴파일 오류

// 잘못된 멤버 함수 호출
class Example {
public:
    void show() { std::cout << "Hello"; }
};
Example obj;
void (Example::*ptr)() = &Example::show;
(obj.*ptr)();  // 올바른 호출 방식

태그: 함수 포인터 std::function 콜백 함수 전략 패턴 함수 객체

10월 4일 12:06에 게시됨