C++的模板(七):左值强制类型转换

C++中有个特殊指针类型,就是指向数据成员的指针。这个数据成员的指针是可以提取出来的。如:

class Whatever {
public:
	int x;
	int z;
};

int  Whatever::*mp;
mp = &Whatever::x;

如果数据的访问权限是private,则这样不可以。但可以通过模板的办法挑出来:

class Whatever {
	int x;
	int z;
};

template <class M, typename T, T M::*mp>
class Savein{
public:
        static void init() { x=mp; }
		static T M::*x;
};

template class Savein<Whatever , int, &Whatever ::x>;
template<> int Whatever::* Savein<Whatever, int, &Whatever::x>::x;

这里必须通过template语法显式声明Savein<Whatever, int, &Whatever::x>这个类。显式声明可以避免访问权限问题。如果没有用这个语法显式实例化这个类,直接用Savein<Whatever , int, &Whatever ::x>仍会碰到访问权限的问题。这样做是妥当的,因为数据成员默认都是private的,如果模板不接受指向private的数据成员的指针,这个语言也就没有这种功能了。

这一步过关之后,可以通过Whatever类的对象或指针和拣出来这个x来访问类的私有数据了,这时已经是运行期问题了。运行期不受访问权限的影响。这也是提取指向数据成员的指针的目的。

Whatever w;
Savein<Whatever, int, &Whatever::x>::init();
w.*Savein<Whatever, int, &Whatever::x>::x =3;

当然这还是累。能不能把Savein的类变量挪到外面来呢?

static unsigned int offset;
template <class M, typename T, T M::*mp>
class Saveout{
public:
        static void init() { reinterpret_cast<T M::*&>(offset)=mp; }
};
template class Saveout<Whatever , int, &Whatever ::x>;

offset对应原来的类变量x。放到外面后offset不能带模板参数了,所以就让它成为整数值了。指向数据成员的指针概念上虽然复杂,实际内容不过是个记录偏移量的小整数。当然还是需要从mp赋值,但不能从mp转换。指向数据成员的指针,除了转换指向其它数据成员的指针,不能转换成别的类型。所以只能从左边想办法。转城右边类型的引用。这是C++特有的左值强制类型转换。

使用时这个offset再重新转换成数据成员的指针:

Whatever w;
Saveout<Whatever, int, &Whatever::x>::init();
w.*(int Whatever::*&)offset =3;

最后,因为offset 已经是整数类型了,可以对它进行调整,从而运行期访问其他数据成员。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值