我要做的是创建一个新的自定义数据类型,它的行为与所有其他原始类型一样。具体地说,此数据类型看起来就像一个固定点分数。我已经创建了一个类来表示这种数据类型,称为“FixedPoint类”,其中有一些方法可以将“FixedPoint”类型转换为“整型”、“双精度型”或“无符号整型”等等。
现在,如果我想从"int" to "FixedPoint"
中进行强制转换怎么办?最初我的解决方案是有一个构造器:
FixedPoint(int i) { /* some conversion from 'int' to 'FixedPoint' in here */ }
此works...but不能放入一个联合中,如下所示:
union {
FixedPoint p;
};
这将中断,因为"FixedPoint“没有隐式的简单构造函数(我们刚刚定义了一个构造函数"FixedPoint(int )”)。
总而言之,整个问题是“我们想要cast from some type T to type FixedPoint without explicitly defining a constructor
,这样我们就可以在联合中使用我们的类型FixedPoint”。
我认为解决方案是:定义一个重载的全局类型转换操作符,将"int“转换为"FixedPoint”,但在网上找不到任何证据。
有没有不使用类构造函数就能做到这一点的方法呢?我希望能够在一个联盟中使用这个类。我尝试过的(在全局范围内):
operator (FixedPoint f, int a) { ... } //compiler complains about this is not a method or non-static.
下面是一个小例子来说明联合不喜欢构造函数(他们喜欢POD)
class bob
{
public:
bob(int a) { m_num = a; }
private:
int m_num;
};
void duck()
{
union
{
bob a;
};
}
在Visual Studio中看到的这个错误是:
error C2620: member 'duck::<unnamed-tag>::a' of union 'duck::<unnamed-tag>' has user-defined constructor or non-trivial default constructor
有什么想法吗?谢谢
发布于 2010-09-28 21:36:01
我很难明白你想用这个做什么。必须不断地确保sizeof(FixedPoint) == sizeof(int)
,并且假设还有其他隐藏的陷阱,比如字节顺序,这似乎很难闻。也许我应该在这里后退一点,联合只是将一个值从一种类型“转换”成另一种类型,因为它需要一块内存,并将其引用为不同的类型。即
union BadConverter
{
int integer;
double fraction;
};
BadConverter.fraction = 100.0/33.0;
BadConverter.integer = ?;
我非常确定,整数不会是3,它将是双精度型的内存块,即整数字节与之共享的内存块。
工会似乎不太适合这类事情。我认为只需要从所有原始类型定义一组赋值操作符即可。即
class FixedPoint
{
FixedPoint& operator=(int value);
FixedPoint& operator=(double value);
..etc..
//Maybe something like this?
template<typename T>
FixedPoint& operator=(const T& value)
{
value = boost::lexical_cast<int>(value);
return *this;
}
}
发布于 2010-09-28 20:57:28
自定义转换运算符必须是要从中转换的类的成员。非平凡的构造函数不是必需的。
编辑:我修改了示例以利用union
,因为这就是您所询问的。
EDIT2:如果你正在尝试另一种方式(构造),并且不需要构造函数,请参见下面的内容。
#include <string>
#include <sstream>
using namespace std;
class FixedPoint
{
public:
operator std::string() const
{
stringstream ss;
ss << x_ << ", " << y_;
return ss.str();
}
int x_, y_;
};
union Items
{
FixedPoint point_;
int val_;
};
int main()
{
Items i;
i.point_.x_ = 42;
i.point_.y_ = 84;
string s = i.point_;
}
如果您试图采用另一种方式--例如,在我的示例中,从int
转换为FixedPoint
--那么通常的方法确实是使用转换构造函数。如果你不想要一个非平凡的构造函数,你必须求助于一个转换函数。
FixedPoint make_fixed_point(int x, int y)
{
FixedPoint ret;
ret.x_ = x;
ret.y_ = y;
return ret;
}
union Items
{
FixedPoint point_;
int val_;
};
int main()
{
Items i;
i.point_ = make_fixed_point(111,222);
}
发布于 2010-09-28 21:07:25
你不能只添加一个默认的构造函数,让它成为联合的一部分吗?
例如:
class bob
{
public:
bob(int a=0) { m_num = a; }
private:
int m_num;
};
void duck()
{
union
{
bob a;
};
}
通过设置a=0
的默认值,它应该能够放入一个联合中。不过,我自己并没有试过。
https://stackoverflow.com/questions/3816912
复制相似问题