指向const与通常指针的指针(用于函数)

时间:2009-07-13 05:55:18

标签: c++ function-pointers

指向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;
}

g ++没有警告。这就是我问的原因。

5 个答案:

答案 0 :(得分:12)

关于C ++ 03,您的代码格式错误。您可以构造一个const(或volatile)限定函数类型。无论何时,你的程序都会变得格格不入。

此规则has been changed适用于C ++ 1x,使编译器忽略const / volatile。即使在C ++ 03模式下,C ++编译器通常也会实现此规则。因此,以下两个将定义相同的函数两次,并导致编译错误。

typedef void Ft();


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

这是我的主张的证明。 C ++ 03,8.3.5/1

  

cv-qualifier-seq只能是非静态成员函数的函数类型的一部分,指向成员的指针引用的函数类型,或函数typedef声明的顶级函数类型。 cv-qualifier-seq在函数声明符中的作用与在函数类型之上添加cv-qualification不同,即它不会创建cv限定的函数类型。实际上,如果在确定类型的任何时候形成了cv限定的函数类型,则该程序是不正确的。

以下是C ++ 1x的文本,8.3.5/7 n2914:

  

cv-quali fi-seq只能是非静态成员函数的函数类型的一部分,指向成员的指针引用的函数类型,或函数typedef声明的顶级函数类型。函数声明符中cv-quali-erq-seq的效果与在函数类型之上添加cv-quali fi cation不同。在后一种情况下,cv-quali firs被忽略。

上面说下面的内容是有效的,并为可以声明const成员函数的函数创建函数类型。

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

答案 1 :(得分:6)

根据定义,独立函数是const。因此,const和非const函数指针之间没有区别。

答案 2 :(得分:1)

我想你的意思,
sum_func* const sum_func_cptr代替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。

答案 3 :(得分: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;
}

答案 4 :(得分:0)

我认为在之前的回复中存在一个基本的误解。

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

这意味着sum_func_cptr是一个指向函数的常量指针,也就是说你可以用非const成员函数初始化它,但是你不能在以后更改它以指向另一个函数,因为{{ 1}}指的是变量。 这相当于:

const
你不同意吗? : - )

-Paolo