2009-07-13 5 views
5

함수에 대한 포인터와 포인터의 차이점은 무엇입니까? 독립형 함수에 const 한정자를 사용하는 것이 적합한 경우? 더 경고를 제공하지 ++const 대 포인터 포인터 (함수 용)

#include <iostream> 
using namespace std; 

int sum(int x, int y) { return x + y; } 
typedef int sum_func(int, int); 

int main() 
{ 
    const sum_func* sum_func_cptr = &sum; // const function 
    sum_func* sum_func_ptr = &sum;  // non-const function ? 

    // What is the difference between sum_func_cptr and sum_func_ptr 

    int x = sum_func_cptr(2, 2); 
    cout << x << endl; 

    int y = sum_func_ptr(2, 2); 
    cout << y << endl; 

    sum_func_cptr = 0; 
    sum_func_ptr = 0; 

    return 0; 
}

그램 :

나는 내 질문을 설명하기 위해 간단한 샘플을 썼다. 그것이 내가 묻는 이유입니다.

답변

12

이 코드는 는 C++ 03과 관련하여을 잘못 형성된다. 이 아닌은 const (또는 휘발성) 규정 된 함수 유형을 구성 할 수 없습니다. 그렇게 할 때마다 프로그램이 잘못 형성됩니다.

이 규칙은 컴파일러가 const/volatile을 무시하도록하기 위해 C++ 1x의 경우 has been changed입니다. C++ 컴파일러는 보통 C++ 03 모드에서도이 규칙을 구현합니다. 따라서 다음 두 함수는 동일한 함수를 두 번 정의하므로 컴파일 오류가 발생합니다.

typedef void Ft(); 


void f(Ft const*) { } 
void f(Ft *) { } // another definition! 

여기에 내 주장의 증거가 나와 있습니다. C++ 03

이력서 - 규정-SEQ 만 비 정적 멤버 함수에 대한 함수 타입의 일부로한다 8.3.5/1 부재 포인터의 참조 또는 최상위 함수 타입 함수 타입 함수 typedef 선언의. 함수 선언자에서 cv-qualifier-seq의 효과는 함수 유형 위에 cv-qualification을 추가하는 것과 동일하지 않습니다. 즉, cv 한정 함수 유형을 작성하지 않습니다. 사실, 유형의 결정에서 언제든지 cv-qualified 함수 유형이 형성되면 프로그램이 잘못 형성됩니다. 여기

는 C++ 1X 용 텍스트 8.3.5/7 n2914이다

이력서-QUALI 인터넷 ER-서열은 비 정적 멤버 함수, 함수 타입에 대한 함수 타입의 일부로한다 멤버에 대한 포인터가 참조하는 함수 유형 또는 함수 typedef 선언의 최상위 함수 유형입니다. 함수 선언자의 cv-qualifier-seq의 효과는 함수 유형의 맨 위에 cv-qualification을 추가하는 것과 동일하지 않습니다. 후자의 경우, cv-qualifier는 무시됩니다.

위의 설명은 유효하지만 const 멤버 함수를 선언 할 수있는 함수의 함수 유형을 만듭니다.

typedef void Ft() const; 
struct X { Ft cMemFn; }; 
void X::cMemFn() const { } 
+0

안녕하세요, 제가 말하는 Standard의 전문가가 있습니다. : P – GManNickG

+0

Hehe, 저는 표준 텍스트로 n00b입니다. 그러나 나는 당신이 분석을 좋아하기 때문에 기뻐요. –

+0

C++ 98 표준을 읽었습니다. 그래서 그걸 찾지 못했습니다. –

1

const sum_func* sum_func_cptr 대신
을 입력하셨습니다.

sum_func* const sum_func_cptr = &sum; 
sum_func* const sum_func_cptr = &sum_new; // will not compile. 
// whereas, 
const sum_func* sum_func_cptr = &sum; // will compile 
const sum_func* sum_func_cptr = &sum_new; // will compile. 
sum_func* sum_func_cptr = &sum; // will compile 
sum_func* sum_func_cptr = &sum_new; // will compile. 

-jagannath.

+0

아니, 나는 내가 작성한 것을 정확하게 의미했다. –

+1

@ jia3ep : 그러면 제목과 설명을 잘못 작성했습니다. "const pointer to X"는 "X * const"를 의미합니다. "const X에 대한 포인터"는 "const X *"를 의미합니다. 너는 그것을 바로 잡아야한다. – newacct

+0

제목과 설명을 수정했습니다. –

6

독립 실행 형 함수는 정의에 따라 const입니다. 따라서 const와 non-const 함수 포인터 사이에는 차이점이 없습니다.

+0

스탠드 얼론 기능에 대한 한정어를 무시하는 표준 정보가 있습니까? 나는 못 찾는다. –

+0

나는 이것을 위해 표준에 어떤 것이 있는지를 알지 못합니다. – Naveen

+0

필자는 내 대답에 최선을 다했지만 분명히 '함수가 const'라고 명시하는 것과 같은 더 나은 것이 있다고 생각한다. – GManNickG

0

흥미롭게도 const 지정자는 멤버 함수에 대한 포인터에 사용 된 경우에도 영향을 미치지 않는 것 같습니다.

#include <iostream> 
using namespace std; 

class Foo { 
public: 
    int sum(int x, int y) { 
    _x = x; 
    _y = y; 
    return x + y; 
    } 
private: 
    int _x; 
    int _y; 
}; 

typedef int (Foo::*sum_func)(int,int); 

int main() 
{ 
    Foo f; 
    const sum_func sum_func_cptr = &Foo::sum; // const pointer 
    sum_func sum_func_ptr = &Foo::sum;  // non-const pointer 

    int x = (f.*sum_func_cptr)(2, 2); 
    cout << x << endl; 

    int y = (f.*sum_func_ptr)(2, 2); 
    cout << y << endl; 

    const sum_func* sum_func_cptr_cptr = &sum_func_cptr; 
    sum_func* sum_func_ptr_ptr = &sum_func_ptr; 

    x = (f.**sum_func_cptr_cptr)(2, 2); 
    cout << x << endl; 

    y = (f.**sum_func_ptr_ptr)(2, 2); 
    cout << y << endl; 

    return 0; 
} 
0

이전 답글에는 기본적인 오해가있었습니다.

const sum_func sum_func_cptr = &Foo::sum; // const pointer 
는 가 sum_func_cptr 함수에 정수 포인터 즉이 아닌 const 멤버 함수를 초기화 할 수있다,하지만 다른 기능을 가리 나중에 변경할 수 없다는 것을 의미

const는 참조하므로 변수에. 해당 내용 :

sum_func const sum_func_cptr = &Foo::sum; // const pointer 

동의하지 않습니까? :-)

-Paolo

+0

const 한정 함수 유형이 없습니다. 그래서'const sum_func stuff = & Foo :: sum;'은 제 대답의 표준 인용문에서 말한 것처럼 말이되지 않습니다. 멤버 함수 포인터를 함수 포인터에 할당하려고 시도하기 때문에'sum_func * const sum_func_cptr = & Foo :: sum;'(* this는 const 함수 포인터입니다)라고 말하는 것은 유효하지 않습니다. 당신은'sum_func Foo :: * const sum_func_cptr = & Foo :: sum;'을해야 할 것입니다. –

+0

나는 이전 게시물을 예로 들었다. 새 형식 "sum_func"를 멤버 함수에 대한 포인터로 정의합니다. typedef int (Foo :: * sum_func) (int, int); "const"는 "sum_func"에 "pointer-to-const-member-function"으로 변경되지 않습니다. 솔직히 나는 그 typedef를 쓰는 것을 모른다. 그리고 함수 유형 만 정의 할 수 있다는 것을 알지 못했습니다. 함수에 대한 포인터 만 있습니다. – Paolo