강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

픽린님의 프로필 이미지
픽린

작성한 질문수

홍정모의 따라하며 배우는 C++

8.11 정적 멤버 함수

11:11 부근에 Something::temp와 Something::getValue의 앞에 &를 붙이는 이유가 뭔가요? (함수 이름은 포인터(주소)가 아닌가요?)

작성

·

31

1

앞에서 '함수이름'은 포인터와 같다라고 배웠습니다. 그래서 실제로 7.9 함수 포인터 강의에서도
int (*ptr_func)() = func; //func는 함수 이름으로 함수포인터를 선언 및 초기화하고 호출 시에도 ptr_func()라고 호출했습니다.

그런데 이번 강의 11:11부근에서 교수님께서 멤버함수의 포인터를 가져올 수 있다 말씀하시면서 선언 및 초기화하실 때
int (Something::*fptr1) = &Something::temp;라고 선언 및 초기화를 해주셨는데

Something::temp 앞에 주소 연산자 [&]를 붙여주는 이유를 모르겠습니다. 검색해보니 함수포인터 초기화 시 함수이름에 &를 붙이지 않았다고 해도 내부적으로 형변환을 해준다고 하는 것을 알았습니다.
실제로 int (Something::*fptr1) = Something::temp;로 주소 연산자 [&]를 붙이지 않았을 때도 에러 없이 정상 작동하는 것을 확인했습니다.

그러나 '함수 포인터는 주소다, 포인터다'라고 배운 개념과 다르게 앞에 &를 붙이지 않으면 내부적으로 자동 형변환 된다는게 모순인 것 같은데
&는 주소를 나타내기 위한 연산자라고 배웠고 원래는 &를 명시적으로 함수이름 앞에 붙이는게 맞다(안붙이면 내부적으로 형변환된다)는 것이 말이 안되는 것 같습니다. 그러면 함수 이름은 포인터가 아닌 것이지 않을까요?

답변 3

0

안녕하세요? 질문&답변 도우미 durams입니다.

모든 함수 포인터가 자동으로 pointer로 decay되는것은 아닙니다. C언어에서는 함수 이름 식별자가 암시적으로 포인터로 decay되는것이 일반적이지만, 클래스가 존재하는 C++에서는 비정적멤버 함수의 경우 어느 클래스의 멤버함수인지, 그리고 어느 인스턴스에서 호출되었는지 그 정보가 필요합니다. 어느 클래스인지는 함수 포인터의 타입으로, 어느 인스턴스인지는 호출 시 지정하게 됩니다.

또한 비정적 멤버 함수의 경우는 함수 포인터 정의 시 &무조건 필요합니다.&를 붙이지 않았을 때에도 에러 없이 정상 작동한다고 하셨지만, 혹 함수가 static으로 되어있지는 않은지 확인이 필요합니다. 대신 정적 멤버 함수는 일반 함수와 동일하게 취급되며, &가 없어도 괜찮습니다.

비정적 멤버 함수에 &를 붙여야 하는 이유는 C++에서 추가된 멤버 함수를 명확하게 처리하기 위함이며, 일반 함수와 정적 멤버함수에는 &를 명시적으로 붙이지않아도 되는 이유는 전통적인 C 구문에 대한 하위 호환성이라고 알려져 있습니다. . C++ draft에는 아래와 같이 작성되어 있습니다.

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses.

함수 이름은 포인터가 아닌 것이지 않냐?는 질문에는... 둘은 원래 같지 않습니다. 배열과 포인터가 엄밀히 같지 않은 것처럼요. 함수의 이름은 컴파일러에 의해 함수가 위치한 주소로 변환될 뿐입니다.

0

픽린님의 프로필 이미지
픽린
질문자

클래스 멤버함수에 대한 포인터를 초기화할 때 주소 연산자 &를 명시적으로 작성해야했다면
int (Something:: * fptr1)() = Something::temp;가 가능했던 이유는 이것도 내부적으로 형변환된건가요? 그러면 클래스 멤버함수 포인터도 주소연산자 &를 붙이는게 필수는 아닌 것으로 이해하면 될까요?

해당 멤버함수가 비정적 함수라면 &를 사용해야합니다. 없다면 컴파일이 불가하며, 작동이 된다면 사용중인 컴파일러가 표준을 준수하지 않고 있다고 볼 수 있습니다. 정적 멤버함수라면 &을 붙이지 않아도 되지만, 명확함을 위해 붙이는 것을 추천드립니다.

참고로 인프런 AI 인턴의 답변은 자동으로 생성 답변으로, 본 강의에서 제공해드리는 공식적인 답변과는 관계가 없으며 정확하지 않을 수 있으니 참고 부탁드립니다.

0

안녕하세요, 인프런 AI 인턴입니다. 픽린님.

질문해 주신 내용은 C++에서 함수 포인터와 멤버 함수 포인터 사용 시의 차이에 대한 것입니다. 간단히 요약하자면, 일반 함수와 클래스 멤버 함수의 포인터는 다르게 처리되고 있습니다.

  1. 일반 함수 포인터

    • 일반 함수 이름은 함수 포인터로 자동 형변환이 가능하기 때문에 & 연산자를 붙이지 않고도 사용할 수 있습니다.
    • 예를 들어 int (*ptr_func)() = func;와 같이 사용할 수 있습니다.
  2. 클래스 멤버 함수 포인터

    • 클래스 멤버 함수를 포인터로 사용할 때는 &를 명시적으로 붙여주어야 합니다.
    • C++에서 멤버 함수는 숨겨진 this 포인터를 갖고 있기 때문에 일반 함수와는 다르게 처리됩니다. 따라서 &Something::temp와 같이 사용해야 합니다.

관련 질문과 답변:
- 계산기 프로그램에서 함수를 포인터 사용법에 대한 혼동

위의 링크에서 질문자의 문제에 대해 기존 답변을 참고하실 수 있습니다. 멤버 함수의 포인터를 사용하는 이유와 방법에 대해 더욱 자세히 설명되어 있습니다.

멤버 함수 포인터와 일반 함수 포인터 사이의 차이점은 클래스 인스턴스가 필요하다는 점입니다. 그렇게 하여 특정 객체의 문맥에서 함수를 호출할 수 있게 됩니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

픽린님의 프로필 이미지
픽린

작성한 질문수

질문하기