静态成员函数和访问运算符
Posted
技术标签:
【中文标题】静态成员函数和访问运算符【英文标题】:Static member function and access operator 【发布时间】:2019-12-12 12:58:09 【问题描述】:我只是从 cppreference.com 浏览左值(值类别),发现member access operator 指定为:
在 E1.E2 类型的内置访问运算符中:
3) 如果 E2 是静态成员函数,则结果是指定该静态成员函数的左值。本质上,在这种情况下,E1 被评估并丢弃;
对于非静态成员函数:
4) 如果 E2 是包含析构函数的非静态成员函数,则结果是一种特殊类型的纯右值,指定 E1 的非静态成员函数只能用作成员函数的左操作数呼叫接线员,不得用于其他目的;
我不知道这意味着什么,尤其是第 3 点)如何用作左值以及用于什么目的。 我知道这是一些很少有人使用的详细内容。但出于好奇,任何对任何示例的帮助都将不胜感激::
【问题讨论】:
【参考方案1】:这是来自 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'
【讨论】:
这并不能解释对静态成员函数的调用如何作为 cppreference 中引用的左值工作...... @Tilak_Chad 所以你的问题是关于“......是一个左值......”。我想现在我明白了这个问题;) 我想你想通过*fun()
打电话给fun
。
@n314159 afaik 都很好【参考方案2】:
考虑:
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()
的调用中,foo
是一个static
成员函数,所以makeX()
对应于E1
在情况3):它因此被评估和丢弃,所以makeX()
被调用,但随后临时的 X
对象被丢弃,foo
被调用,就像您输入了 X::foo()
一样。
在对makeX().bar()
的调用中,bar
是一个非static
的成员函数,所以makeX()
被求值,临时的X
对象被用作调用的this
参数bar
.
【讨论】:
【参考方案3】:例如,您可以获取静态成员函数的地址并将其存储在普通函数指针中(因此不是成员函数指针):
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
没有问题。
您可以将公共静态成员函数大致视为可通过结构/类访问的免费友元函数(不完全是,但它比非静态成员函数更接近)。
【讨论】:
以上是关于静态成员函数和访问运算符的主要内容,如果未能解决你的问题,请参考以下文章