为什么这段代码会编译?

时间:2012-01-03 05:42:36

标签: c++ function-pointers

我有一个代码。

class A
{
public:
    int foo(int i)
    {
        return i;
    }
};

int foo(int i)
{
    return i;
}

int (A::*ptrFoo)(int) = NULL;
int (*_foo)(int) = NULL;

int  main()
{
    ptrFoo = &A::foo; 
    _foo = foo;

    (*_foo)++++++++++++++(10);   //This dont compile...

    A a;
    (a.*ptrFoo)+++++++++++++++++(10);  //This compiles ????

}
请告诉我它是什么?一个未定义的行为或什么???我在VS2008中编译了它。最后一行代码编译成功。

2 个答案:

答案 0 :(得分:2)

两个表达式都不应该编译:在C ++中,您不能对指向函数或成员函数的指针或函数类型或成员函数执行算术运算。程序中的两个表达式分别尝试对函数和成员函数执行算术运算。

如果编译器接受第二个表达式,则是由于编译器中的错误。

答案 1 :(得分:1)

首先请注意指向函数的指针指向成员函数的指针不同。

您的第一个示例是指向普通函数的指针。它包含函数的实际内存地址。当你取消引用它((*_foo))时,你会获得函数本身,并且函数(函数指针)上包括++的算术运算是没有意义的。

第二个是另一个故事,指向类成员函数的指针不包含内存中函数的地址。实际上,编译器如何管理成员函数是特定于实现的。指向成员函数的指针可能包含某些地址或某些特定于编译器的信息。这种类型的算术也没有意义。

因此,我们不知道(a.*ptrFoo)的价值是什么,但在您的情况下,MSVC2008设法编译它,或者是因为错误或设计。

顺便说一句,GCC没有编译这两个语句中的任何一个,并且两者都有错误。

无论你使用偶数+还是奇数,上面都是如此;无论如何我们正在做算术。 (如果有一个奇数的+,则没有函数调用,如第二个例子中那样,你将函数递增8次,然后最后剩下的+将10加到结果中。 ,这没关系:我们正在尝试更改函数/成员函数指针。)