[ c++ ] 함수포인터, 멤버 함수포인터

채명석·2021년 12월 27일
1

cpp

목록 보기
7/11

함수 포인터란?

함수도 다른 변수들 처럼 주소를 가지고 있는데 이 함수의 주소를 포인터 변수에 저장해서 사용하는 걸 함수 포인터라고 합니다.

선언의 형태는 다음과 같습니다.

int	(*f)(int, int);

// int - 리턴타입
// (*f) - 변수 이름 f를 함수포인터로 선언
//(int, int) 함수의 매개변수

이렇게 선언하면 함수의 주소값을 저장할 수 있는 f라는 함수포인터가 만들어집니다.

f라는 포인터 안에 함수의 주소를 저장해서 사용할 수 있습니다.

#include <iostream>

using namespace std;

int	add(int a, int b)
{
	return (a + b);
}

int	main(void)
{
	int	(*f)(int, int);

	f = add; // 함수 add를 함수 포인터 f에 저장.

	cout << f(1, 2) << endl;
}
//출력 
//3

매개변수로 사용할 수 있는 함수 포인터

함수 포인터도 다른 변수와 동일하게 매개변수로 사용이 가능합니다.

#include <iostream>

using namespace std;

int	add(int a, int b)
{
	return (a + b);
}

void	print_odd(int a, int b, int (*f)(int, int)) //매개변수로 함수 add를 받음
{
	int	ret = f(a, b);

	if (ret % 2 == 1)
		cout << ret << endl;
	else
		cout << "홀수가 아니에요!" << endl;
}

int	main(void)
{
	print_odd(2, 4, add);
	print_odd(2, 3, add);
}
//출력
//홀수가 아니에요!
//5

함수포인터의 const

함수포인터도 다른 변수들과 동일하게 const를 사용할 수 있습니다.

#include <iostream>

using namespace std;

int	add(int a, int b)
{
	return (a + b);
}

int	main(void)
{
	int	(*const f)(int, int) = add; 
	//참조 연산자 *옆에 const를 붙여주면 함수포인터 f를 상수화 시킬 수 있습니다.

	cout << f(1, 2);
}
//출력
//3

class 멤버함수의 함수포인터 사용

class의 멤버함수도 함수포인터로 사용이 가능합니다.
하지만 class내부의 멤버함수는 객체를 통해서만 출력이 가능하고, 함수포인터의 선언 또한 해당 클래스의 범위 내에있는 함수포인터라고 명시해줘야 사용이 가능합니다.

#include <iostream>

using namespace std;

class Test
{
public:
	int	add(int a, int b) //클래스 Test안에 멤버함수 add가 있습니다.
	{
		return (a + b);
	}
};

int	main(void)
{
	Test	test;  // 클래스 Test를 인스턴스화 시켜 객체로 만듭니다.
	int	(Test::*f)(int, int) = &Test::add;
	//함수포인터 f는 Test의 멤버함수를 사용하겠다고 Test::를 통해 명시해줍니다.
	//그리고 함수의 주소 또한 Test의 멤버함수라고 명시해 주고 다른 함수 포인터와 달리
	//항상 명시적으로 &연산자를 통해 함수의 주소를 가져와야 합니다.

	cout << (test.*f)(1, 2) << endl;
	//함수포인터의 사용 또한 해당 클래스의 객체를 통해서 사용해야 합니다.
	//만약 class의 멤버함수 내에서 함수포인터를 사용한다면 this를 통해서 접근할 수 있습니다.
	//접근은 멤버 포인터 연산자인 .* 또는 ->*연산자로 접근해야 합니다.
}
//출력
//3

진짜 못 알아 먹게 생겼다.

static을 이용한 멤버함수의 접근

함수포인터 정말 못 생긴 것 같아요.
하지만 아직 하나 더 남았어요. 그래도 이건 일반 함수포인터와 비슷하게 사용합니다.
class에서 멤버함수에 static을 사용하면 class의 이름으로 해당 함수에 접근이 가능하고, 어떤 특정 객체에 귀속되는게 아니라고 했었습니다.
그렇기 때문에 class의 이름을 통해서 접근만 해주면 일반 함수포인터와 동일하게 사용이 가능합니다.

#include <iostream>

using namespace std;

class Test //class를 총 4개 생성한 뒤 멤버함수 모두 static을 사용해 줍니다.
{
public:
	static int	add(int a, int b)
	{
		return (a + b);
	}
};

class TestTwo
{
public:
	static int	sub(int a, int b)
	{
		return (a - b);
	}
};

class TestThree
{
public:
	static int	div(int a, int b)
	{
		return (a / b);
	}
};

class TestFour
{
public:
	static int	mul(int a, int b)
	{
		return (a * b);
	}
};

int	main(void)
{
	//함수포인터의 배열을 선언해주고, class의 이름을 통해서 함수의 주소를 저장해줍니다.
	int	(*f[4])(int, int) = {
		&Test::add,
		&TestTwo::sub,
		&TestThree::div,
		&TestFour::mul
	};
	for (int i = 0; i < 4; i++)
		cout << f[i](1, 2) << endl;
 		//출력은 일반 함수포인터와 동일합니다.
}
//출력
//3
//-1
//0
//2

참고

소년코딩C++ 08.09 - 함수 포인터
C++ 에서 멤버 함수포인터 사용하기

[ c++ ] namespace
[ c++ ] 클래스, 생성자, 소멸자, 이니셜라이저, this포인터
[ c++ ] c++에서의 const와 static
[ c++ ] 참조자(reference)
[ c++ ] new와 delete
[ c++ ] 함수 오버로딩
[ c++ ] 파일 입출력 (ifstream, ofstream)
[ c++ ] 함수포인터, 멤버 함수포인터
[ c++ ]연산자 오버로딩
[ c++ ] 캡슐화란?
[ c++ ] 상속과 다형성에 대해 알아보자

0개의 댓글