C++ 任意类型Any

可以使用任意类型的类型就是 void* 了。只需要强制转换类型即可,任意使用。编译器并不会严重警告。我们不应该滥用。

void*并没有过多约束,是万能的类型。
执行任意操作都可以编译通过
需要自己管理指向的对象

  char szBuf[4] = "";
  void* p = szBuf;
  *(int*)p = 1234567889;
  *(long long*)p = 12345678891212121LL; //隐患

所以,我们自己做一个接受任意类型的类。为了能够任意类型赋值,该类应该与类型无关。

  Any a = 12;
  a = "1234";
  Any b = a;

给出实现。
定义一个保存数据类型的类。该类是派生类。

class BaseHolder
{
public:
  BaseHolder() { }
  virtual ~BaseHolder() { }
  virtual BaseHolder* clone() = 0;
};

template<typename T>
class Holder : public BaseHolder
{
public:
  Holder(const T& t)
    : _value(t)
  { }
  ~Holder() { }
  BaseHolder* clone() override
  {
    return new Holder<T>(_value);
  }
public:
  T _value;
};

建议不要使用void*来持有对象,因为当Any对象拷贝给另外一个Any对象时,void*并没有方法提供数据类型以供拷贝,并且释放对象时也并不安全,有内存隐患,如下例。

class Text
{
public:
  Text(){}
  ~Text() { cout << "~Text()"; }
};
void* p = new Text;
delete p;

    template<typename ValueType>
  Any(const ValueType& value)
  {
    _pValue = new Holder<ValueType>(value); 
  }

  Any(const Any& any) : _pValue(any._pValue->clone())
  { }

  template<typename ValueType>
  Any& operator=(const ValueType& value)
  {
    Any tmp(value);
    if (_pValue)
      delete _pValue;
    _pValue = tmp._pValue;

    return *this;
  }

Any类的构造函数和赋值函数(赋值函数不能马虎赋值,this对象的值是Any类型时会无限递归)。


类型转换函数。

  template<typename ValueType>
  ValueType* anyCast()
  {
    Holder<ValueType>* p = dynamic_cast<Holder<ValueType>*>(_pValue);
    return p ? &p->_value : NULL;
  }
  template<typename ValueType>
  ValueType& anyRefCast()
  {
    return (dynamic_cast<Holder<ValueType>& >(*_pValue))._value;
  }

dynamic_cast需要虚函数的支持,我们的保存数据类型的类已经提供。注意,强制类型转换引用是会抛出异常的。

Any类全部代码

class BaseHolder
{
public:
  BaseHolder() { }
  virtual ~BaseHolder() { }
  virtual BaseHolder* clone() = 0;
};

template<typename T>
class Holder : public BaseHolder
{
public:
  Holder(const T& t)
    : _value(t)
  { }
  ~Holder() { }
  BaseHolder* clone() override
  {
    return new Holder<T>(_value);
  }
public:
  T _value;
};

class Any
{
public:
  template<typename ValueType>
  Any(const ValueType& value)
  {
    _pValue = new Holder<ValueType>(value); 
  }

  Any(const Any& any) : _pValue(any._pValue->clone())
  { }

  ~Any()
  {
    if (_pValue)
      delete _pValue;
  }

  template<typename ValueType>
  Any& operator=(const ValueType& value)
  {
    Any tmp(value);
    if (_pValue)
      delete _pValue;
    _pValue = tmp._pValue;
        tmp._pValue = NULL;
    return *this;
  }

  template<typename ValueType>
  ValueType* anyCast()
  {
    Holder<ValueType>* p = dynamic_cast<Holder<ValueType>*>(_pValue);
    return p ? &p->_value : NULL;
  }

  template<typename ValueType>
  ValueType& anyRefCast()
  {
    return (dynamic_cast<Holder<ValueType>& >(*_pValue))._value;
  }
private:
  BaseHolder* _pValue;
};

测试代码

int main()
{
  Any a = 1.23f;
  Any b = 2;
  Any c = a;
  Any d = 12345678999999ULL;
  cout << *a.anyCast<float>() << endl;
  try{
    cout << b.anyRefCast<float>() << endl;
  }
  catch (std::bad_cast) {
    //error
    cout << "bad_cast" << endl;
  }
  cout << c.anyRefCast<float>() << endl;
  cout << d.anyRefCast<unsigned long long>() << endl;
  a = string("hello");
  cout << a.anyCast<char*>() << endl;
  cout << *a.anyCast<string>() << endl;
  return 0;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值