1. win7+vs2010下配置Boost开发环境
之前在ubuntu下编译安装了Boost,但是来回切换环境还挺麻烦,所以今天先在win7下配置Boost开发环境,IDE是vs2010.同样下载的是boost_1_54_0版本,解压到E盘,运行E:\boost_1_54_0目录下的bootstrap.bat文件,会生成b2.exe文件。点击执行b2.exe,出去溜一圈,回来后如果编译完了会在boost_1_54_0目录下生成stage/lib目录,该目录下就是所需要的lib库文件,为了节约空间,删除生成bin.v2目录,ok,现在可以开始了。

打开vs2010,创建一个空的win32控制台项目,然后右击项目》属性》VC++目录,设置包含目录(E:\boost_1_54_0)和库目录(E:\boost_1_54_0\stage\lib),如下图:

2. timer库
timer库是一个很小的库,可以用于计时和进度显示。包含三个组件:timer、progress_timer、progress_display。
2.1 timer
timer组件是一个计时器,可以用它来计算某代码块运行消耗的时间,进行性能测试,也可以用它来实现定时执行某项任务。它提供毫秒级别的计时精度,一般来说用于普通的时间处理也够了。但它不适合高精度或者大跨度的时间处理,在win32下测试发现它的最大时间跨度才几百个小时。下面的代码实现了获取timer最大时间范围和最小测量精度、某几行代码执行的时间以及模拟定时打印字符。

#include <windows.h>
#include <iostream>
#include <boost/timer.hpp>

using namespace std;
using namespace boost;

int main()
{
	timer t;
	cout << "max timespan: " << t.elapsed_max() / 3600 << "h" << endl;
	cout << "min timespan: " << t.elapsed_min() << "s" << endl;
	Sleep(500);
	cout << "elapsed: " << t.elapsed()<< endl;

	int i = 0;
	t.restart();
	while(true)
	{
		if(t.elapsed() >= 3)
		{
			cout << "send message" << endl;	
			++ i;
			t.restart();
		}

		if(i == 3)
		{
			break;	
		}

	}

	system("pause");
	return 0;
}

运行结果如下图:

2.2 progress_timer
progress_timer也是一个计时器,继承自timer,但它会在析构时自动调用elapsed()输出时间,不需要手动去调用,使用起来很方便,但它对外输出精度只有0.01s,可以对它进行扩展,调用ostream的precision(N)函数,设置输出流显示浮点数的位数。下面的代码实现了测量每个代码块的执行时间。

#include <windows.h>
#include <iostream>
#include <boost/progress.hpp>

using namespace std;
using namespace boost;

int main()
{
	{
		progress_timer t;
		Sleep(500);
	}

	{
		progress_timer t;
		Sleep(300);
	}

	system("pause");
	return 0;
}

运行结果如下图:

2.3 progress_display
对于一些很耗时的操作,可以用progress_display在控制台展示程序的执行进度。

#include <windows.h>
#include <iostream>
#include <vector>
#include <boost/progress.hpp>

using namespace std;
using namespace boost;

int main()
{
	vector<int> v(100);
	progress_display pd(v.size());
	for(int i = 0; i < v.size(); ++ i)
	{
		Sleep(100);
		++ pd;
	}

	system("pause");
	return 0;
}

运行结果如下图:


它有一个缺陷,因为它是向标准输出(std::cout)输出字符,所以如果使用progress_display的程序也有其他输出,那么进度条就会混乱,可以用下面的方法解决。

	progress_display pd2(v.size());
	for(int i = 0; i < v.size(); ++ i)
	{
		Sleep(100);
		pd2.restart(v.size());
		pd2 += (i + 1);
		//++ pd2;
		cout << "**alexzhou**" << endl;
	}

3. date_time库
date_time库是一个日期时间库,基于我们日常使用的公历(格利高里历),它提供了与时间相关的各种操作,也是boost中少数需要编译的库之一。在使用date_time库之前,先来了解下面几个概念:
时间点:如果把时间想象成一个向前和向后都无限延伸的实数轴,那么时间点就是数轴上的一个点。
时间段:时间段是两个时间点之间确定的一个区间。
时长:时间长度则是一个有正负号的标量,它是两个时间点之差,不属于数轴。
这三者之间可以进行运算。
3.1 处理日期
首先来学习date_time库的日期处理部分,它仅支持1400-Jan-01 to 9999-Dec-31之间的日期计算,位于名字空间:boost::gregorian,如果使用date_time库的日期功能,需要包含头文件<boost/date_time/gregorian/gregorian.hpp>。
date类是date_time库处理日期的核心类,使用一个32位的整数作为内部存储。
日期长度类date_duration是以天为单位的时长,是度量时间长度的一个标量,它有另外一个名字:days。
日期区间类date_period是时间轴上的一个左闭右开区间,端点是两个date对象,区间的左值必须小于右值。
日期迭代器包括date_iterator,week_iterator,month_iterator,year_iterator,分别以天,周,月,年为单位递减。

#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>

using namespace std;
using namespace boost::gregorian;

int main()
{
	cout << "***创建日期***" << endl;
	{
		date d1;
		date d2(2013, 8, 4);
		date d3(2013, Aug, 4);
		date d4(d2);
		date d5 = from_string("2013-8-4");
		date d6 = from_string("2013-08-04");
		date d7 = from_string("2013/8/4");
		//不能写成"201384"
		date d8 = from_undelimited_string("20130804");
		date d9(max_date_time);
		date d10(min_date_time);

		//超过了范围,不存在的月份或日期,都会抛出异常
		//date d11(10000,1,100);

		cout << "d1: " << d1 << endl;
		cout << "d2: " << d2 << endl;
		cout << "d3: " << d3 << endl;
		cout << "d4: " << d4 << endl;
		cout << "d5: " << d5 << endl;
		cout << "d6: " << d6 << endl;
		cout << "d7: " << d7 << endl;
		cout << "d8: " << d8 << endl;
		cout << "d9: " << d9 << endl;
		cout << "d10: " << d10 << endl;
	}
	cout << "**********访问日期******************************************************************" << endl;
	{
		date d1(2013, 8, 4);
		cout << "year: " << d1.year() << "; month: " << d1.month() << "; day: " << d1.day() << endl;
		date::ymd_type ymd = d1.year_month_day();
		cout << "year: " << ymd.year << "; month: " << ymd.month << "; day: " << ymd.day << endl;
		// 返回date的星期数,0表示星期天
		cout << "day of week: " << d1.day_of_week() << endl;
		// 返回date是当年的第几天(最多是366)
		cout << "day of year: " << d1.day_of_year() << endl;
		// 返回当月的最后一天的date对象
		cout << "end of month: " << d1.end_of_month() << endl;
		// 返回date所在的周是当年的第几周(0-53),如果年初的几天位于去年的周,那么则周数是53,即第0周
		cout << "week number: " << d1.week_number() << endl;
	}
	cout << "***********输入日期*****************************************************************" << endl;
	{
		date d(2013, 8, 4);	
		cout << "to simple string: " << to_simple_string(d) << endl;
		cout << "to iso string: " << to_iso_string(d) << endl;
		cout << "to iso extend string: " << to_iso_extended_string(d) << endl;
	}
	cout << "***********与tm结构的互换************************************************************" << endl;
	{
		date d(2013, 8, 4);	
		tm t = to_tm(d);	
		cout << "tm_year: " << t.tm_year << "; tm_month: " << t.tm_mon << "; tm_day: " << t.tm_mday << "; tm_hour: " << t.tm_hour << "; tm_min: " << t.tm_min << endl; 
		date d2 = date_from_tm(t);
		cout << "date from tm: " << d2 << endl;
	}
	cout << "***********日期长度************************************************************" << endl;
	{
		date_duration d1(10);	
		days d2(10), d3(-10);
		cout << "d1 == d2: " << (d1 == d2) << endl;
		cout << "d2 > d3: " << (d2 > d3) << endl;
		weeks w(3);
		cout << "3 weeks = " << w.days() << " days" << endl;
		months m(5);
		years y(2);
		months m2 = y + m;
		cout << "number of months = " << m2.number_of_months() << endl;
		cout << "number of years = " << y.number_of_years() << endl;
	}
	cout << "***********日期运算************************************************************" << endl;
	{
		date d1(2000, 1, 1), d2(2008, 8, 8);	
		cout << "d2 - d1 = " << (d2 - d1) << " days" <<endl;
		d1 += days(10);
		cout << "d1 = " << d1 << endl;
		d1 += months(2);
		cout << "d1 = " << d1 << endl;
		d1 -= weeks(1);
		cout << "d1 = " << d1 << endl;
		d1 -= years(7);
		cout << "d1 = " << d1 << endl;
	}
	cout << "***********日期区间************************************************************" << endl;
	{
		date_period dp1(date(2000, 1, 1), date(2008, 8, 8));
		date_period dp2(date(2000, 1, 1), days(20));
		cout << "dp begin day: " << dp1.begin().day() << endl;
		cout << "dp last day: " << dp1.last().day() << endl;
		cout << "dp end day: " << dp1.end().day() << endl;
		cout << "dp length days: " << dp1.length().days() << endl;
		cout << "dp2: " << dp2 << endl;
	}
	cout << "***********日期迭代器**********************************************************" << endl;
	{
		date d(2013, 8 ,4);
		cout << "d: " << d << endl;
		day_iterator d_iter(d);
		++ d_iter;
		cout << "after ++ day_iter day: " << d_iter->day() << endl;
		year_iterator y_iter(*d_iter, 3);
		++ y_iter;
		cout << "after ++ year_iter year: " << y_iter->year() << endl;
	}
	cout << "***********其他功能**********************************************************" << endl;
	{
		cout << "2013 is " << (gregorian_calendar::is_leap_year(2013) ? "" : "not") << " a leap year" << endl;
		cout << "2013 8 end of month day:  " << gregorian_calendar::end_of_month_day(2013, 8) << endl;
	}

	system("pause");
	return 0;
}

运行结果:


3.2 处理时间
date_time库最高可以提供纳秒级别的时间精度,时间功能位于名字空间:boost::posix_time,为了使用时间组件,需要包含头文件:<boost/date_time/posix_time/posix_time.hpp>
首先了解下时间长度类time_duration,它表述了时分秒的度量。它有下面这几个子类,可以度量不同的时间分辨率。
hours,minutes,seconds,millisec/milliseconds,microsec/microseconds,nanosec/nanoseconds。
ptime是date_time库处理时间的核心类,它使用64位(微秒)或96位(纳秒)的整数在内部存储时间数据,相当于一个日期再加上一个小于一天的时间长度,依赖于date和time_duration。时间区间time_period和时间迭代器time_iterator可参考日期区间和日期迭代器。

#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>

using namespace std;
using namespace boost::gregorian;
using namespace boost::posix_time;

int main()
{
	{
		time_duration td1(1, 10, 30, 1000);
		time_duration td2 = hours(1) + minutes(10) + seconds(30) + millisec(1);
		time_duration td3 = duration_from_string("1:10:30:001");
		cout << "td1: " << td1 << endl;
		cout << "td2: " << td2 << endl;
		cout << "td3: " << td3 << endl;
		cout << "hours: " << td3.hours() << "; minutes: " << td3.minutes() << "; seconds: " << td3.seconds() << endl;
		cout << "tota seconds: " << td3.total_seconds() << endl;
		cout << "simple string: " << to_simple_string(td3) << endl;
		cout << "iso string: " << to_iso_string(td3) << endl;

		tm t = to_tm(td3);
		cout << "to tm hours: " << t.tm_hour << "; minutes: " << t.tm_min << "; seconds: " << t.tm_sec << endl;
	}
	cout << "*********************************ptime************************************" << endl;
	{
		ptime p1(date(2013, 8, 4), hours(22));
		cout << "p1: " << p1 << endl;
		ptime p2 = time_from_string("2013-8-4 22:53:00");
		cout << "p2: " << p2 << endl;
		ptime p3 = from_iso_string("20130804T225300");
		cout << "p3: " << p3 << endl;
		//获取当前时间
		ptime p4 = second_clock::local_time();
		cout << "p4: " << p4 << endl;
		ptime p5 = microsec_clock::universal_time();
		cout << "p5: " << p5 << endl;

		cout << "to simple string: " << to_simple_string(p1) << endl;
		cout << "to iso string: " << to_iso_string(p1) << endl;
		cout << "to iso extend string: " << to_iso_extended_string(p1) << endl;

		tm t = to_tm(p1);
		cout << "to tm hours: " << t.tm_hour << "; minutes: " << t.tm_min << "; seconds: " << t.tm_sec << endl;

		ptime p6 = from_time_t(std::time(0));
		cout << "p6: " << p6 << endl;

		ptime p7(date(2013, 8, 4), hours(10));
		for(time_iterator t_iter(p7, minutes(10)); t_iter < p7 + hours(1); ++ t_iter)
		{
			cout << *t_iter << endl;	
		}
	}

	system("pause");

	return 0;
}

运行结果:

4. 格式化日期和时间
在上面的代码末尾添加下面的代码块:

	cout << "*******************************格式化日期************************************" << endl;
	{
		date d(2013, 8, 4);
		date_facet* p_dfacet = new date_facet("%Y年%m月%d日");
		cout.imbue(locale(cout.getloc(), p_dfacet));
		cout << "date_facet: " << d << endl;

		time_facet* p_tfacet = new time_facet("%Y年%m月%d日 %H点%M分%S%F秒");
		cout.imbue(locale(cout.getloc(), p_tfacet));
		cout << "time_facet: " << ptime(d, hours(21) + minutes(50) + millisec(100)) << endl;
	}

运行结果:

lua面向对象模拟简介

lua不是面向对象语言,但可以通过表(table)和元表(metatable)来模拟。table 是 lua 中唯一的一种数据结构,它可以用来描述原始的数组、符号表、集合、 记录、...

阅读全文

在c/c++中调用lua函数

上篇文章完成了在lua中调用c/c++函数,现在来实现在c/c++中调用lua函数。 首先完成lua代码,创建sum.lua: function add(x, y) return x + y; end 为了...

阅读全文

在lua中调用c/c++函数

lua是一种轻量级的脚本语言,用来扩展c和c++非常好,在游戏开发中使用很普遍。 首先下载lua,因为我是在win7下,所以我这里下载了luaforwindows,安装到F:\Lu...

阅读全文

4 条评论

  1. 为什么我使用date_facet不会输出你的结果,代码如下:
    date d8(2010, 3, 6);
    date_facet *dfacet = new date_facet(“%Y年%m月%d日”);
    cout.imbue(locale(cout.getloc(),dfacet));
    cout << dfacet << endl;

欢迎留言