静态成员函数和访问运算符

时间:2019-12-12 12:58:09

标签: c++ lvalue static-functions

我只是浏览cppreference.com的左值(值类别),遇到了member access operator,它指定为:

E1.E2类型的内置Access运算符:

  

3)如果E2是静态成员函数,则结果是一个表示该静态成员函数的左值。本质上,在这种情况下,将评估E1并将其丢弃;

和非静态成员函数:

  

4)如果E2是包含析构函数的非静态成员函数,则结果是一种特殊的prvalue,它指定E1的非静态成员函数只能用作成员函数的左操作数呼叫运营商,无其他目的;

我不知道这意味着什么,尤其是3号点如何用作左值以及用于什么目的。 我知道这是一些任何人都很少使用的详细资料。.但是出于好奇,任何示例方面的任何帮助都将受到赞赏::

3 个答案:

答案 0 :(得分:2)

这是cppreference的简化示例

#include <iostream>
struct A
{
    int f() { return 10; }
    static int sf() { return 4; }
};

int main()
{
    A a;
    std::cout << a.f() << a.sf(); // A::sf() also works
}

现在,您引用的部分指出a.sf是左值,而a.f不是。这意味着什么?这意味着您可以使用a.sf的地址:

auto fun = &(a.sf); 
fun();

a.f却不是这样:

auto fun = &(a.f);   // error 
// ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say '&A::f'

答案 1 :(得分:1)

例如,您可以获取静态成员函数的地址,并将其存储在普通函数指针中(而不是成员函数指针中):

struct X {
    static void f(int);
    void g(int);
};

int main() {
    X x;
    void (*p)(int);
    p = &x.f; // works
    p = &x.g; // does not work
}

这也很有意义,因为您可以调用f(仅)而不提供类型为X的对象,而您只能在提供此类对象时调用g。由于您希望能够通过*p(0)调用函数指针,因此在&g没问题的情况下,您不能允许将p分配给&f

您可以将公共静态成员函数粗略地视为可通过struct / class访问的免费朋友函数(不完全是,但它比非静态成员函数更近)。

答案 2 :(得分:1)

考虑:

struct X{
    static void foo(){}

    void bar(){}
};

X makeX(){
  std::cout<<"make X called"<<std::endl;
  return X();
}

int main(){
  makeX().foo();
  makeX().bar();
}

在对makeX().foo()的调用中,foostatic的成员函数,因此makeX()对应于情况3)的E1:因此被求值并被丢弃,因此将调用makeX(),但随后会丢弃临时X对象,并像您键入foo一样调用X::foo()

在对makeX().bar()的调用中,bar是一个非static成员函数,因此对makeX()进行求值,并使用了临时X对象作为this调用的bar参数。