可以使用任意类型的类型就是 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;
}