《c++ primer》6.7章节
《c++程序设计语言 第四版》12.5章节、20.6章节
1、定义和使用
由函数体生成的代码存在于内存中的某处,因此有它自己的地址,函数指针不能修改它指向的代码。
函数指针的类型和函数的返回值与形参类型有关,与函数名无关。
声明一个函数指针,只需要用指针名称替换函数名称就行了。
void debugValue(const int & value)
{
qDebug()<<value;
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
void (*p)(const int &) = &debugValue;//也可以写作: = debugValue;
p(999);
}
2、函数指针的别名
如果函数名称很长参数很多,那么定义和使用函数指针的时候就不很方便,这时候可以给类型起个别名:
-
给该类型的函数起个别名
void debugValue(const int & value)
{
qDebug()<<value;
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
typedef void (fun)(const int &);
fun * f = &debugValue;
(*f)(888);
}
相等的写法,使用decltype关键字推断出类型(根据表达式推断类型的关键字:decltype):
typedef decltype(debugValue) fun;
fun * f = &debugValue;
(*f)(888);
- 给该类型的函数指针起个别名
void debugValue(const int & value)
{
qDebug()<<value;
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
typedef void (*funP)(const int &);
funP f = &debugValue;
f(888);
}
相等的写法:
typedef decltype(debugValue) * funP;
funP f = &debugValue;
f(888);
3、函数指针作为形参
void debugValue(const int & value)
{
qDebug()<<value;
}
void showValue(int value,
void (*funP)(const int &))
{
funP(value);
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
showValue(4444,debugValue);
}
形参里的:
void (*funP)(const int &)
可以写成如下,编译器会自动转换的:
void funP(const int &)
4、函数指针作为返回值
如果真的遇到这种情况,那么应该给函数指针设置别名,返回别名。
5、类的成员函数指针
class A
{
public:
void debugValue(int aa)
{
debug aa;
}
};
using A_Pointer = void (A::*)(int);//指向返回类型为void,参数为一个int的指针类型
int main(int argc, char *argv[])
{
A a;
A_Pointer p = &A::debugValue;
(a.*p)(10000);//调用a的debugValue()函数(括号不能少...)
}
6、类的成员变量指针
class A
{
public:
QString string = "hello";
};
using A_Pointer = QString A::*;//指向A中QString类型的成员变量的指针类型
int main(int argc, char *argv[])
{
A a;
A_Pointer p = &A::string;
debug (a.*p);//"hello"
}
子类的成员变量指针可以指向基类的成员:
class A
{
public:
QString string = "hello";
};
class B : public A
{
public:
QString stringB = "world";
};
using B_Pointer = QString B::*;
int main(int argc, char *argv[])
{
B b;
B_Pointer p = &A::string;
debug (b.*p);//"hello"
}
7、类的静态成员函数指针
与普通成员函数指针相比,静态成员函数指针不用加类名称。
class A
{
public:
static void test(int & i)
{
}
};
using A_static_pointer = void (*)(int &);
int main(int argc, char *argv[])
{
A_static_pointer = &A::test;
}
注:函数指针不能赋给void*,可以赋给nullptr。