我正在尝试为两种类似的类型提供统一的界面,一种处理double
s,另一种处理float
s。
class float_type {
float_type() { /* does floaty stuff */ }
float f();
};
class double_type {
double_type() { /* does doubly stuff */ }
double f();
};
我想编写一个分配一个或另一个的类,具体取决于程序需要做什么。
将float_type::f()
转换为double的结果我完全没问题。事实上,它无论如何都会发生。
我试着像这样写:
class union_type {
bool is_double;
char mem[ sizeof(double_type) > sizeof(float_type)
? sizeof(double_type) : sizeof(float_type) ];
public:
float_or_double_value_reader(bool is_double)
: is_double(is_double)
{
if (is_double) new(mem) double_type();
else new(mem) float_type();
}
~float_or_double_value_reader() {
if (is_double) delete static_cast<double_type*>(mem);
else delete static_cast< float_type*>(mem);
}
double f() {
return (is_doubled
? static_cast<double_type*>(mem)->f()
: static_cast< float_type*>(mem)->f()
);
}
};
但我得invalid static_cast from type 'char [128]' to type 'double_type'
。
我知道我可以添加一个成员指针来指向new
返回的内容,
但那是多余的,因为我已经知道mem
的位置,
所以我想避免这种情况。
如果我使用reinterpret_cast
,我会在free(): invalid pointer:
被销毁时在运行时获得union_type
。
这里适当的投射方法是什么?
答案 0 :(得分:2)
reinterpret_cast
应该是适当的投射方法。
但是,你不能简单地delete reinterpret_cast<double_type*>(mem)
,因为这不仅会破坏对象,还会释放内存,就好像它是用new
分配的那样 - 它不是。
您可以使用reinterpret_cast<double_type*>(mem)->~double_type();
销毁对象而不尝试释放内存。
当然,上述内容也适用于float_type
。
答案 1 :(得分:0)
更好的选择是提供铸造操作员。
我本可以为float类提供一个隐式double
转换运算符来实现相同的接口
答案 2 :(得分:0)
您可以使用模板基类:
#include <iostream>
template < typename T >
class base_decimal
{
public:
base_decimal(T data) : _data(data) {}
virtual ~base_decimal() {}
T f() { return this->_data; }
base_decimal& operator=(T val) { this->_data = val; }
operator T() { return this->_data; }
friend std::ostream& operator<<(std::ostream& os, const base_decimal& bd)
{
os << bd._data;
return os;
}
private:
T _data;
};
class float_type : public base_decimal<float>
{
public:
float_type(float f) : base_decimal<float>(f)
{
// do float stuff
}
};
class double_type : public base_decimal<double>
{
public:
double_type(double d) : base_decimal<double>(d)
{
// do double stuff
}
};
int main(int argc, char* argv[])
{
float_type f = 1.2f;
double_type d = 2.2;
std::cout << "f = " << f << std::endl;
std::cout << "d = " << d << std::endl;
double rd = d;
double rf = f;
std::cout << "rf = " << rf << std::endl;
std::cout << "rd = " << rd << std::endl;
return 0;
}