转换操作符转换类型:普通函数指针(普通函数、类的静态函数)、类的成员函数指针

        一、转换操作符的定义

        转换操作符是一种特殊的类成员函数它定义将类类型值转变为其他类型值的转换,转换操作符在类定义体内声明,在保留字operator之后跟着转换的目标类型,转换函数采用如下通用形式:

operator type();

        这里,type表示内置类型名、类类型名 或 由类型别名所定义的名字,本文讨论转换普通函数指针类型、转换类的成员函数指针类型

        二、转换普通函数指针类型

        在类内定义类型别名,定义转换函数,把类对象转换为普通函数指针,代码如下:

#include <iostream> 

void f(){   //普通函数
	std::cout << "f()";
}

struct A{
	typedef void (*fp)(); //类型别名//using fp = void (*)(); //C++11标准
	operator fp (){       //转换函数//A类对象转换为普通函数指针
		return ::f;
	}
};

int main()
{	
	A a;	
	A::fp p = a;	//A作用域的类型别名fp//将对象a转换为普通函数指针
	p();

	return 0;
}

        三、转换类的静态函数为普通函数指针类型

        因为运算符的优先级,函数指针解引用要加括号

#include <iostream> 

struct A{
	typedef void (*fp)(); //类型别名//using fp = void (*)(); //C++11标准
	operator fp (){       //转换函数//A类对象转换为普通函数指针
		return A::f;
	}
	static void f(){  std::cout << "static void A:: f()\n"; }//静态函数
};

int main()
{	
	A a;	
	A::fp p = a;	//A作用域的类型别名fp//将对象a转换为普通函数指针
	//A::f();
    //p();
	(*p)();//运算符优先级,要加括号

	return 0;
}

        四、转换类的成员函数指针类型

        .*和->*两个操作符,能够将成员指针绑定到实际对象,左操作数必须是类类型的对象或类类型的指针,右操作数是该类型的成员指针

#include <iostream> 

struct A{
	using fp = void (A::*)();//类成员函数指针
	operator fp (){ //转换函数//A类对象转换为A类成员函数指针
		return A::f;
	}
	void f(){ std::cout << "A::f()\n"; }	
};


int main()
{	
	A a;
	A::fp p = a;    //A对象a转换为类的成员函数指针类型
	(a.*p)();  		//对象a使用操作符.*调用成员函数f
	A *ap = new A;
	(ap->*p)();     //类类型指针使用操作符->*调用成员函数
	delete ap;
	
	return 0;
}

        可以把私有的成员函数转换为成员函数指针,因为转换函数是公有的,转换函数可以在类内访问私有成员,我们把对象转换一下,达到了对象可以调用私有的成员函数目的,看起来真的好神奇

#include <iostream> 

struct A{
	using fp = void (A::*)();//类成员函数指针
	operator fp (){ //转换函数//A类对象转换为A类成员函数指针
		return A::f;
	}
private:
	void f(){ std::cout << "A::f()\n"; }	//私有的成员函数
};


int main()
{	
	A a;
	A::fp p = a;    //A对象a转换为类的成员函数指针类型
	(a.*p)();  		//对象a使用操作符.*调用成员函数f
	
	return 0;
}

          fp私有也可以

#include <iostream> 
 
struct A{
private:
	using fp = void (A::*)();//类成员函数指针
public:
	operator fp (){ //转换函数//A类对象转换为A类成员函数指针
		return A::f;
	}
private:
	void f(){ std::cout << "A::f()\n"; }	//私有的成员函数
};
 
 
int main()
{	
	A a;
	//using fp = void (A::*)();
	//fp p = a;
	void (A::*p)() = a;
	(a.*p)();  		//对象a使用操作符.*调用成员函数f
	
	return 0;
}

           五、成员函数指针作为函数的参数,类对象隐式转换

#include <iostream> 

struct A{
	using fp = void (A::*)();//类成员函数指针
	operator fp (){ //转换函数//A类对象转换为A类成员函数指针
		return A::f;
	}
private:
	void f(){
		std::cout << "A::f()\n";
	}
};

void test( A::fp p){ //成员函数指针作为函数参数
	A b;
	( b.*p )();      //成员函数指针,调用成员函数
}

int main()
{	
	A a;
	test(a); //类型转换//A对象a转换为A类成员函数指针

	return 0;
}

        六、不用转换操作符,只用公有的成员函数指针变量,对象一样可以访问私有成员函数 

#include <iostream> 

struct A{
	using fp = void (A::*)();//类成员函数指针
	fp p = A::f; //公有成员变量
private:      //私有的成员函数
	void f(){
		std::cout << "A::f()\n";
	}
};

int main()
{	
	A a,b;
	( a.*(a.p) )();
	//( a.*(b.p) )();  //说明p是对象的就可以	

	return 0;
}

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值