[置顶] C/C++左值性精髓(三)左值转换----从函数到指针的转换

 

[置顶] C/C++左值性精髓(三)左值转换----从函数到指针的转换

分类: C/C++左值性精髓   2514人阅读  评论(14)  收藏  举报

 C/C++左值性精髓

(三)左值转换

 

3.从函数到指针的转换

 

        将函数转换为指针的目的,与数组到指针的转换一样,都是为了将符号数值化,以利于表达式计算。该条款规定:

 

        A function designator is an expression that has function type. Except when it is the operand of thesizeofoperator or the unaryoperator, a function designator with type ‘‘function returningtype’’ is converted to an expression that has type ‘‘pointer to function returningtype’’.

 

除了几种例外,一个具有函数类型的函数指示符被转换为指向该函数实体的指针。在C中,严格来讲,函数到指针的转换并不属于左值转换,因为C中的函数既不是左值,也不是右值,也正因为这个原因,C中的条款内容并没有指出转换的左值性。但对于C++,函数属于左值,因此该转换属于左值转换,结果是一个右值指针。

        关于C++函数的左值性,有一个例外,就是非静态成员函数不是左值。笔者最初对此感到非常迷惑,因为从抽象本质上说,非静态成员函数并没有不符合C++左值涵义之处。笔者曾经向C++的创始人Bjarne Stroustrup博士发了一封email,向他请教这个问题,BS在回复中说,他认为这个规定是一种不太优雅的技术处理方式,以区别普通函数和非静态成员函数。就是说,这是一个人为规定。由于非静态成员函数被剔除出左值范畴,也导致非静态成员函数不存在从函数到指针的转换,非静态成员函数指针必须通过&运算符获得,例如:

 

struct A

{

void foo( void );

};

 

void ( A::*p )( void ) = A::foo;      //A

void ( A::*q )( void ) = &A::foo;     //B

 

A是错误的,因为非静态成员函数的隐式转换不存在,B才是正确的。

        对于使用函数指针进行函数调用,存在两种方式,分别为:

 

p();           //A

( *p )();      //B

 

两种方式都是合法的。因为,函数调用表达式要求其后缀表达式操作数的类型是函数指针,使用普通函数名进行函数调用时,其实是先将函数名转换为函数指针再进行调用的。这是第一种方式成立的原因。而第二种方式,*是解引用运算符,对一个函数指针进行解引用的结果是该指针指向的函数类型,然后该函数类型又通过函数到指针的转换变回函数指针类型,最后再进行函数调用。两种方式其实是殊途同归。第二种方式还可以产生某些有趣的形式,例如:

 

( ***p )();

( **********p )();

( ************************p )();

 

这些解引用运算符可以用上述类似的方式无限填充下去,但结果都是一样的,只需要不断进行解引用和函数指针转换就行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值