指向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 = ∑ // const function
sum_func* sum_func_ptr = ∑ // 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 ++没有警告。这就是我问的原因。
答案 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_func* const sum_func_cptr = &sum_new; // will not compile.
// whereas,
const sum_func* sum_func_cptr = ∑ // will compile
const sum_func* sum_func_cptr = &sum_new; // will compile.
sum_func* sum_func_cptr = ∑ // 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