今天闲来无事,做了两个C++测试用例
1. 定义一种普通函数 类型
2. 如何理解返回函数的函数
1.
#include <iostream.h>
typedef void funcType(); //定义一种普通函数 类型 ,正常开发中用函数指针类型
void test()
{
cout<<"test"<<endl;
}
/*
funcType felixFunc()
{
return &test; //返回一个指定类型的函数
}
编译器报错:
function returns function 错误类型
A function cannot return a function. Return a pointer to a function instead.
上面为编译器手册说明,所以函数不能返回一个普通的函数,
必须是一个指向函数的指针,所以需要加一个*
*/
funcType* felixFunc()
{
return &test; //返回一个函数的地址,注意这里可以去掉&,编译器可以隐式的找到地址
}
int main()
{
/*
由于返回一个指针*类型的函数,所以这里也要顶一个指针变量
*/
funcType *f = felixFunc();
f();
(*f)();
//或者直接调用
felixFunc()();
return 0;
}
a) typedef void funcType( ); 定义一种普通函数 类型 ,正常开发中用函数指针类型,如
typedef void (*funcType)( );
b) 不可以定义下面的函数,编译器的手册提示一个函数不能返回一个普通函数类型,必须是一个指向函数的指针类型,也就是为什么我们正常开发中使用函数指针类型,而不是普通的函数类型的原因
funcType felixFunc()
{
return &test;
}
c)由于我们将funcType 用typedef进行了定义,所以是一种新的类型,这种类型的特点是: 函数返回值为void,且参数也为void。
既然是一种类型,就可以定义变量了,于是我们定义一个变量funcType f;
但是如何初始化这个变量呢?
首先我们知道,一般情况下函数不能作为 = 运算符的左值,也就是说 f = ... .这样显然是不行的。解决办法就是我们可以将 f声明为一个指针就可以了
funcType *f;
f= felixFunc();
或者
funcType *f = felixFunc();
d ) 如何通过函数指针变量调用函数呢,方法如下
f();
(*f)();
//或者直接调用
felixFunc()();
(*felixFunc)()();
用函数指针的方式就是
#include <iostream.h>
typedef void (*funcType)();
void test()
{
cout<<"test"<<endl;
}
funcType felixFunc()
{
return test; //或者return &test;
}
int main()
{
funcType f = felixFunc();
f();
(*f)();
//或者直接调用
felixFunc()();
(*felixFunc)()();
return 0;
}
2.
上面在定义一个函数类型的时候使用了typedef关键字,正常开发中我们都是大量的使用typedef关键字,目的是方便开发和维护
typedef void (*funcType)();
如果这里不使用typedef,那么函数的返回值为一个函数的时候,如
funcType felixFunc()
{
return test; //或者return &test;
}
应该如何理解呢?也就是说该如何展开呢?
下面简单的讨论一下,请正常开发中不要这么使用,首先难理解,其次是你的代码给同事看,维护代码都是个问题,这里只做研究,实际开发中用typedef就够了
首先看一段代码
//返回值为void,参数为void的函数类型
typedef void (*new_handler)();
//声明一个函数,返回值为函数,且参数也为函数
new_handler set_new_handler( new_handler );
用typedef开始来是不是很容易理解呢,我们实际开发中建议用这种方式
好了,看看展开后是个什么样子,做好心理准备
void ( *set_new_handler(void (*)() ) ) (); // 语法正确,但是不友好
linux 中编程中就会经常遇到这种形式。
如何理解呢?我们分三步走
第一步:
首先写函数的返回值,为一个指向函数的指针
void (*)()
第二步:
写函数名称,难理解的是这里
void (*)() set_new_handler(new_handler) //人的思维,但是编译器认为是错误的
正确的是将set_new_handler(new_handler)放到括号里,且*号的后面
void (*set_new_handler(new_handler) )()
第三步:替换函数的参数
void (*set_new_handler(void (*)()) )()
这样是不是理解能好些
或许这样你会明白点:
#include <iostream>
using namespace std;
int p(int x,int y)
{
int n = x>y?x:y;
return n;
}
int (*getFuncPtr())(int,int)
{
return p;
}
int main(){
int (* funPtr)(int,int) = getFuncPtr();
cout<<funPtr(10,10)<<endl;
return 0;
}
/*
第二个函数getFuncPtr是这个函数的函数名称,里面的括号()是它本身的参数括号符来得。
而它前面的*表示返回的是一个指针,后面的()表示了这是一个函数指针,并且该函数指针
所指向的函数有两个int类型的参数,最前面的int表示该函数指针所指向的函数返回值为
int型的。
然后,在main函数中定义一个函数变量来接收getFuncPtr返回的函数指针值。
int (* funPtr)(int,int) = getFuncPtr();
int (* funPtr)(int,int) 表示定义一个函数变量 funPtr,如果用typedef 就很容易理解了,然后 getFuncPtr() 返回一个函数赋值给 funPtr
*/