是否有可能在c++中创建一个联合,让我做这样的事情…
union myTime {
long millis;
double seconds;
};
但是,让它以某种方式进行转换,以便如果我以毫秒为单位输入时间,然后调用秒,它将获取该数字并将其除以1000,或者相反,如果我以秒为单位输入数字,然后调用毫秒,它将将该数字乘以1000…
:
myTime.millis = 1340;
double s = myTime.seconds;
其中s等于1.34
或
myTime.seconds = 2.5;
long m = myTime.millis;
其中m = 2500
这可能吗?
union
只是相同值(相同字节)的不同表示,因此您无法在其上定义任何智能逻辑。
在这种情况下,可以用转换函数定义class
(用于初始化或获取数据)。
class myTime {
public:
myTime(long millis);
double as_seconds();
static void from_seconds(double seconds);
};
请注意,正如在其他答案中提到的,对于时间转换,您可以使用std::chrono
对象(c++11及以上)
回答问题:不联合是一种低级结构,它只允许多个对象表示存在于相同的内存空间中。在您的示例中,long
和double
共享同一个地址。
然而,它们还不够智能,无法自动进行任何类型的对话。在大多数情况下,访问union
的非活动成员实际上是未定义的行为(如果在标准布局对象中有一个公共初始序列,则有例外)。
即使行为是定义良好的,您将在double
中看到的值将是double
对表示1340
所需的字节模式的解释。
如果您的问题是专门与将millis
转换为seconds
有关,根据您的示例,您是否考虑使用std::chrono::duration
单元?这些单元是专门为自动完成时间单位之间的转换而设计的——并且您可以使用自定义表示(例如double
)定义持续时间。
你的问题中的例子可以重写:
using double_seconds = std::chrono::duration<double>;
const auto millis = std::chrono::millis{1340};
const auto m = double_seconds{millis};
// m contains 1.340
如果你滥用类型系统,你可以:
union myTime {
double seconds;
class milli_t {
double seconds;
public:
milli_t &operator=(double ms) {
seconds = ms/1000.0;
return *this; }
operator double() const { return seconds * 1000; }
} millis;
};
现在如果你做了
myTime t;
t.millis = 1340;
double s = t.seconds;
s等于1.34
和
myTime t;
t.seconds = 2.5;
long m = t.millis;
m将是2500,完全符合您的要求。
当然,为什么要这样做还不清楚。