C++ 万能指针void *实现任意类型的数据存储(上)

        这几天,在设计任意类型的数据存储、管理类时,被一个问题卡住了很久,即如何设计一个类,任意类型可以转化到它,并且它也可以根据需要转回去呢?

       后者好说,前者猛地一看,这不用template就搞定了吗,然而,并没有这么简单。比如我们用类模板T作用于我们的类,假设叫Data,任意类型的数据存在变量data中:

template <class T>
class Data {
public:
   ...
private:
   T data;
};

但是,这样做,Data类在实例化对象时,需要提供类型:

Data<int> d(123);

若Data被另一个类Manager引用,并把Data的实例化对象存在其成员变量里:

class Manager {
public:
   ...
private:
   vector<Mdata<int>> buffer;
};

这样做只能把Mdata<int>的数据存储,即在声明时就锁死了它的类型,可我们并不想这样,因为类型是不确定的,甚至动态调整的。并且想通过一个Manager就可以管理任何类型。

如果把Manager也被template作用:

template <class T>
class Manager {
public:
   ...
private:
   vector<data<T>> buffer;
};

这样Manager实例化一个对象也需要显示声明类型,并且buffer的Mdata也会变成这个相同的类型,但是我们想要实现一个多类型的Manager,那么将template作用于变量不就可以了?


class Manager {
public:
   ...
private:
   template <class T>
   vector<Data<T>> buffer;
};

然而,此时编辑器会报错:

成员 "Manager::buffer" 不是有效的类成员模板C/C++(786)

<error-type> Manager::buffer

template是不能作用于成员变量的,但是成员函数和类等可以。[虚函数也不可以]

那么在Data的设计时,就不能设计成模板类,然而数据怎么存呢?

我们可以用万能指针void *保存:

class Data {
public:
   ...
private:
   void * ptr{nullptr};
};

然后将,模板类作用于构造函数即可(或者其他传数据的函数)

class Data {
public:
   template <class T>
   Data(T data){

   }
private:
   void * ptr{nullptr};
};

在传入data后,可以直接ptr指向data:

class Data {
public:
   template <class T>
   Data(T data){
     ptr = &data;
   }
private:
   void * ptr{nullptr};
};

 第一个问题,即存储解决了,那如何变回来呢?

直接强制类型转换指针类型,然后取地址即可。

class Data {
public:
   template <class T>
   Data(T data){
     ptr = &data;
   }
   template <class T>
   T transferToOriginalData()
   {
       T *res_ptr{(T *)ptr};
       return *res_ptr;
   }

private:
   void * ptr{nullptr};
};

样例:

string str = “1234”;
Data d(str);
auto res = d.tansforToOriginData<string>();
cout<<res;

这样,通过输入字符串str存储d中,然后调用模板类作用的函数,声明它的类型,就能得到存储的字符串了,同时,Manager也不需要考虑变量的模板类问题。


class Manager {
public:
   ...
private:
   vector<Data> buffer;
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值