상세 컨텐츠

본문 제목

[C++] 함수 포인터

C++

by 이나시오- 2024. 3. 19. 23:56

본문

  지난 포스트에서 변수의 포인터에 대해서만 다루었는데, 함수도 포인터를 사용할 수 있다. 우리가 작성한 코드는 기계어로 바뀌어 모두 코드영역에 저장되는데, 함수 포인터는 함수의 내용이 저장된 주소를 가리키는 것이다. 사실 사용한 경험도 거의 없고, 선언 방식도 좀 생소해서 내용을 정리해두려고 글을 작성하게 되었다.

 

    함수포인터 선언 방법        

   함수 포인터를 선언하는 방식 : 반환타입(*변수 이름)(인자 타입)

 

  예를 들어 아래와 같이 반환 타입이 int고, 인자를 받지 않는 함수를 pFunc이라는 포인터 변수에 받고 싶다면, int(*pFunc)(void) = &func;이라고 선언할 수 있다. void 는 인자가 없음을 의미한다. 반환타입이 void인 경우는 void(*pFunc)(void)로 선언하면 된다. 그리고 이 포인터에 받는 값은 &func이라고 써야 하지만, '&'를 떼고 func라고만 써도 동일하게 작동한다. 함수의 이름 자체가 함수의 주소를 의미하도록 되어있기 때문이다.

 

  이후 그 포인터변수에 ()를 붙여서 함수처럼 실행할 수 있게 된다.

#include <iostream>

int func ()
{
    printf("func() called\n");
    return 0;
}


int main()
{
    // 선언
    int(*pFunc)(void) = &func;
    pFunc = func;
    
    // 실행
    pFunc();

    return 0;
}

 

 

  사실 이것만 봐선 어떻게 활용해야할 지 감이 잘 오지 않는다. 아래에서 iostream 라이브러리의 endl을 간단하게 구현해보며 이해해보자.

 

    함수포인터 사용 예제 std::endl        

  연산자 오버로딩을 활용해 std::cout과 std::endl과 같이 구현해 보았다. 아직 레퍼런스 변수나 클래스에서 static 키워드의 활용에 대해 정리하지 않아서 비교적 단순하게 구현했다.

 

  우선 MyOStream 클래스의 << 연산자를 2가지 버전으로 오버로딩 했다.

  첫 번째는 const char*로 인자를 받는데, 문자열을 수정하지 않고 받겠다는 의도로 const char*로 인자를 받고, 내부에서 printf()를 이용해서 출력하고 종료된다.. 리턴타입은 MyOStream인데, << 연산자를 연달아서 사용하기 위해 << 연산이 한 번 일어나고나서 MyOStream 객체를 반환한다. 예를 들어 main 함수에서 MyCout << "Hi!!" 를 실행하고 나서 MyOStream 객체가 반환되므로 바로 다시 << 연산자를 사용할 수 있게 되는 것이다.

  두 번째 오버로딩은, 함수 포인터를 인자로 받아서 그 함수를 실행하고 종료한다. 그리고 클래스 밖에서 리턴 타입이 void이고 인자를 받지 않는 MyEndl()함수를 구현해두었고, main 함수에서 << 연산자의 피연산자로 MyEndl 함수의 주소를 받는 것이다. 그러면 두 번째 오버로딩 함수로 들어와서 MyEndl의 함수를 실행하고, 종료된다. 이 때 MyEndl이 개행 문자를 출력하므로 std::endl과 같이 동작하게 되는 것이다.

 

  실제로 std::endl로 함수로 구현되어 있다.

#include <iostream>

void MyEndl ()
{
    printf("\n");
}

class MyOStream
{
public:
    MyOStream operator << (const char* _str)
    {
        printf(_str);
        return *this;
    }
    
    void operator << (void(*_pFunc)(void))
    {
        _pFunc();
    }
};

int main()
{
    MyOStream MyCout;
    
    MyCout << "Hi!!" << MyEndl;

    return 0;
}

 

'C++' 카테고리의 다른 글

[C++] 함수 객체 (Functor)  (0) 2024.08.08
[C++] 포인터  (0) 2024.03.19
[C++] Struct (구조체)  (0) 2024.03.12
[C++] 변수의 종류와 메모리 영역  (0) 2024.03.01
[C++] 자료형 (Data Type)  (0) 2024.02.29

관련글 더보기