为了账号安全,请及时绑定邮箱和手机立即绑定

你好,能帮我说下为什么函数也可以做为类型吗?

你好,能帮我说下为什么函数也可以做为类型吗?

C++ C
紫衣仙女 2022-05-14 15:11:40
class B {public:void f(){;}typedef void (B::*pf)();void f2(pf pf) {(this->*pf)();}void f3() {f2(f);}};这段代码的意思帮我讲一下,我看不懂.谢谢!
查看完整描述

2 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

函数的类型是函数原型去除所有非类型标识符。
例如原型为int foo(float f, double d);的函数,它的类型是int(float, double)。(LS“函数不能作为类型”当然正确,函数不是类型;不过恐怕理解有误,函数还是有类型的。)
函数类型被用于声明函数,但不能定义函数,因为函数不是对象,C/C++不提供对于函数定义的初始化语法。
例如
int foo1(float f, double d);
int foo2(float f, double d);
int foo3(float f, double d);
可以简化为
typedef int footype(float, double);
footype foo1, foo2, foo3;
函数类型的主要应用是用于模板类型参数。例如template<R(P1, P2)>,函数类型R(P1, P2)是这里的模板类型参数。boost等库中有很多这类技巧。
上例中函数对应的函数指针类型为int (*)(float, double);。指针是对象,它可以被定义并初始化。并且,它可以作为函数的参数和返回值(函数本身就不行)。C语言中利用函数指针是通用函数回调的唯一手段。
例如(续上例):
int (*p1)(float, double) = &foo1;//函数类型在这里可以退化为对应函数指针类型,&可以省略。
footype* p2 = foo2;
int (*p3)(float, double) = NULL;
注意,这里要求源文件或库中有foo1、foo2的定义,否则会链接失败。定义时不能直接用footype,要老老实实写int foo1(float f, double d)之类作为函数头。
调用时,函数指针可以直接当作函数名称使用,例如p1(1.0f, 1.0d);。
此外,C++中还有函数引用。上例中对应的类型是int(&)(float, double)。具体用法类似,参照对象引用和对象指针的区别。
对于成员函数,有成员函数指针(但没有成员函数引用)。和对象指针不同,成员指针的值的含义比较模糊,取决于实现(编译器)。(题外话,对成员函数指针的sizeof结果也取决于实现,对于虚继承的成员函数,有些编译器中可达20。)一般来说,成员函数指针保存了成员在类定义中的偏移量信息。根据成员函数指针和对应类的实例,可以利用二元操作符->*和.*(不能被重载)运算符调用这个函数,左操作数为指向对象的指针或对象,右操作数为成员函数指针。
例如LZ的例子中,this->*pf,也可以用(*this).*pf来调用成员函数指针pf指向的成员函数。



查看完整回答
反对 回复 2022-05-16
?
三国纷争

TA贡献1804条经验 获得超7个赞

typedef void (B::*pf)();
定义了一个指针,这个指针指向B中的一个函数,此函数没有参数也没有返回值。这个指针是一个新类型,名字是pf,以后可以定义pf类型的变量。

void f(){;}
在类B中定义了一个函数f,无参数无返回值。

void f2(pf pf) {
(this->*pf)();
}
定义了函数f2,参数是pf类型的,无返回值。f2函数中,会将参数pf指向的函数执行一次。

void f3() {
f2(f);
}
定义了函数f3.无参数,无返回值。其中调用了f2函数,参数是f。f代表函数f的地址。

==========补充============
函数本身是不可以做类型的,但是指向函数的指针是可以的。这里的pf实际上是一个指向函数的指针。



查看完整回答
反对 回复 2022-05-16
  • 2 回答
  • 0 关注
  • 152 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信