Timestamp类封装
继承muduo::copyable
muduo::copyable 空基类,标识类,表示值类型;
值语义:可以拷贝的,拷贝后,与原对象脱离关系
对象语义:要么不能拷贝;要么可以拷贝,但拷贝后仍与原对象存在一定的关系,比如共享底层资源(要实现自己的拷贝构造函数)
1. BOOST_STATIC_ASSERT
我下载的版本里是没有这个宏的;但是实现都是一样的,使用boost库的static_assert
static_assert(sizeof(Timestamp) == sizeof(int64_t),
"Timestamp should be same size as int64_t");
static_assert 编译时断言
assert 运行时断言
2. 使用PRld64
string Timestamp::toString() const
{
...
snprintf(buf, sizeof(buf), "%" PRId64 ".%06" PRId64 "", seconds, microseconds);
...
}
int64_t表示64位整数,32位系统中是long long int, 64位系统中是long int,所以打印int64_t的格式化方法是:
printf("%ld", value); //64bits OS
printf("%lld", value); //32bits OS
跨平台的做法是:
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#undef __STDC_FORMAT_MACROS
printf("%" PRld64 “\n”, value);
因为在usr/include/inttypes.h中有定义:
# if __WORDSIZE == 64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
# else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
# endif
...
# define PRId64 __PRI64_PREFIX "d"
3. 格式化输出
string Timestamp::toFormattedString(bool showMicroseconds) const//当前时间戳转换为格式化字符串
{
char buf[64] = {0};
time_t seconds = static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
struct tm tm_time;
gmtime_r(&seconds, &tm_time);//由秒数创建结构体,_r表示为线程安全的函数
if (showMicroseconds)
{
int microseconds = static_cast<int>(microSecondsSinceEpoch_ % kMicroSecondsPerSecond);
snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d",
tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
microseconds);
}
else
{
snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d",
tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec);
}
return buf;
}
由now()获取当前时间,创建time结构体,然后转换为格式化字符串
4.Timestamp实现及测试
Timestamp Timestamp::now()
{
struct timeval tv;
gettimeofday(&tv, NULL);
int64_t seconds = tv.tv_sec;
return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);//返回时间戳对象
}
这个now()函数是Timestamp类的静态成员函数,功能是将当前时间用于初始化Timestamp对象并返回;
以下使用tests文件夹内的timestamp_unittest.cc进行测试
...
void benchmark()
{
...
for (int i = 0; i < kNumber; ++i)
{
stamps.push_back(Timestamp::now());
}
printf("%s\n", stamps.front().toString().c_str());
printf("%s\n", stamps.back().toString().c_str());
printf("%f\n", timeDifference(stamps.back(), stamps.front())); //放1000000个time的时间差
...
}
...
int main()
{
Timestamp now(Timestamp::now()); //拷贝构造函数,外面的now是Timestamp对象;里面的是Timestamp的静态成员函数
printf("%s\n", now.toString().c_str());
passByValue(now); //值传递
passByConstReference(now); //引用传递
benchmark();
}
测试放入1000*1000个时间戳需要多长时间,并打印时间差。