C/C++开发语言系列之20---C++类成员函数指针2

2020腾讯云共同战“疫”,助力复工(优惠前所未有!4核8G,5M带宽 1684元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1054

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

推荐:C++语言笔记系列之十——静态成员

[1.静态成员(1)由关键字static修饰静态变量定义语句在编译阶段就执行,运行过程中不再执行。(2)分类:静态数据成员、静态成员函数。(3)静态成员时类的所有对象共享的

测试目录:

1.普通函数指针指向普通函数
2.普通函数指向非静态成员函数
3. 类外部的 类函数指针 指向普通函数
4. 类外部的 类函数指针 指向成员函数
5. 类内部的 函数指针 指向成员函数 (类似于第2条)
6. 类内部的 函数指针 指向普通函数


直接上代码:
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
 
class Foo
{
    public:
        string m_str;
        Foo()
        {
            m_str = "";
        }
		
		static void testFunc2(int a)
		{
			cout<<"Foo:void testFunc2(int a)"<<endl;
			cout<<a<<endl;
		}
		
		void testFunc4(int a)
		{
			cout<<"Foo:void testFunc4(int a)"<<endl;
			cout<<a<<endl;
		}
		static void testFunc5(int a)
		{
			cout<<"Foo:void testFunc5(int a)"<<endl;
			cout<<a<<endl;
		}
		
		void (*pTestFunc5)(int a);
		void (*pTestFunc6)(int a);
};

void (*pTestFunc1)(int a);
void (*pTestFunc2)(int a);
void (Foo::*pTestFunc3)(int a);
void (Foo::*pTestFunc4)(int a);

void testFunc1(int a)
{
	cout<<"func1 pointer test"<<endl;
	cout<<a<<endl;
}

void testFunc3(int a)
{
	cout<<"func3 pointer test"<<endl;
	cout<<a<<endl;
}

void testFunc6(int a)
{
	cout<<"func6 pointer test"<<endl;
	cout<<a<<endl;
}


int main(int argc, const char *argv[])
{

    Foo foo;
	//foo.test("woo",100);
	
	pTestFunc1 = testFunc1;		//经常用这个方法
	(*pTestFunc1)(1);
	
	 pTestFunc2=&foo.testFunc2;
	(*pTestFunc2)(2);
	
	//pTestFunc3 = &testFunc3;  //编译器报错,不可以这么使用
	
	pTestFunc4 = &Foo::testFunc4; //初始化的时候必须带有&Foo::

	//pTestFunc4(4);//编译器报错,不可以这么使用
	//foo.pTestFunc4(4);//编译器报错,不可以这么使用
	//foo.*pTestFunc4(4);//编译器报错,不可以这么使用
	//foo.(*pTestFunc4)(4);//编译器报错,不可以这么使用
	(foo.*pTestFunc4)(4);	//正常运行
	
	foo.pTestFunc5=&Foo::testFunc5;
	foo.pTestFunc5(5);
	
	foo.pTestFunc6=&testFunc6;
	foo.pTestFunc6(6);
	
    return 0;
}



程序分析: 1.普通函数指针指向普通函数
pTestFunc = &testFunc;
或者
pTestFunc = testFunc;
调用方式
pTestFunc(1)
(pTestFunc)(1)
(*pTestFunc)(1)


2.普通函数指向非静态成员函数
pTestFunc=foo.testFunc2;  编译器报错,提示不匹配
error: argument of type ‘void (Foo::)(int)’ does not match ‘void (*)(int)’


pTestFunc=&foo.testFunc2;  编译器报错,提示不匹配
error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say ‘&Foo::testFunc’
error: cannot convert ‘void (Foo::*)(int)’ to ‘void (*)(int)’ in assignment


pTestFunc=Foo::testFunc2;  编译器报错
error: invalid use of non-static member function ‘void Foo::testFunc(int)’


pTestFunc=&Foo::testFunc2; 编译器报错
error: cannot convert ‘void (Foo::*)(int)’ to ‘void (*)(int)’ in assignment


普通函数指向静态成员函数 将代码更改一下后,

推荐:C++语言中数组指针和指针数组彻底分析(系列一)

[近来在论坛中机场经常看到有关数组指针和指针数组的讨论。这个是学习c++等语言中不可少的步骤, 不过向来指针的东西就是很有用但是也是很难用的东西,所以学习起来也不是

将成员函数前加入一个static关键字
则下面的初始化方式编译和运行正常
pTestFunc2=Foo::testFunc2;
pTestFunc2=&Foo::testFunc2;
pTestFunc2=foo.testFunc2;
pTestFunc2=&foo.testFunc2;
调用方式和普通函数指向普通函数一致
pTestFunc2(2)
(pTestFunc)2(2)
(*pTestFunc)2(2)




3. 类外部的 类函数指针 指向普通函数
这种用法就是错误的,所以编译器不通过
pTestFunc3 = testFunc3;  编译器报错,
test5.cpp:83: error: cannot convert ‘void(int)’ to ‘void (Foo::*)(int)’ in assignmen
pTestFunc3 = &testFunc3;
test5.cpp:83: error: cannot convert ‘void (*)(int)’ to ‘void (Foo::*)(int)’ in assignmen


4. 类外部的 类函数指针 指向成员函数
初始化指针的方式
pTestFunc4 = &Foo::testFunc4; //初始化的时候必须带有&Foo::
pTestFunc4 = Foo::testFunc4; //编译器报错
pTestFunc4 = foo.testFunc4; //编译器报错
pTestFunc4 = &foo.testFunc4; //编译器报错


调用方式:
pTestFunc4(4);//编译器报错,不可以这么使用
foo.pTestFunc4(4);//编译器报错,不可以这么使用
foo.*pTestFunc4(4);//编译器报错,不可以这么使用
foo.(*pTestFunc4)(4);//编译器报错,不可以这么使用
(foo.*pTestFunc4)(4) //正常运行,所以必须要带有括号
如果foo为指针
Foo *foo=new Foo();
(foo->*pTestFunc4)(4)




5. 类内部的 函数指针 指向成员函数 (类似于第2条)
foo.pTestFunc5=foo.testFunc5;  编译器报错
test5.cpp:125: error: argument of type ‘void (Foo::)(int)’ does not match ‘void (*)(int)’


foo.pTestFunc5=&foo.testFunc5; 编译器报错
test5.cpp:123: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say ‘&Foo::testFunc’
test5.cpp:123: error: cannot convert ‘void (Foo::*)(int)’ to ‘void (*)(int)’ in assignment


foo.pTestFunc5=Foo::testFunc5; 编译器报错
foo.pTestFunc5=&Foo::testFunc5;  编译器报错


声明为静态函数后(与第2条相似),编译和运行都OK
foo.pTestFunc5=foo.testFunc5;
foo.pTestFunc5=&foo.testFunc5;
foo.pTestFunc5=Foo::testFunc5;
foo.pTestFunc6=&Foo::testFunc5;

6. 类内部的 函数指针 指向普通函数
编译和运行都OK
foo.pTestFunc2=testFunc6;
foo.pTestFunc2=&testFunc6;

测试代码的下载位置: http://download.csdn.net/download/maojudong/4778348


推荐:C/C++开发语言系列之3--static 类成员

[静态成员的提出是为了解决数据共享的问题。实现共享有许多方法,如:设置全局性的变量或对象是一种方法。但是,全局变量或对象是有局限性的。这一章里,我们主要讲述类的

相关推荐