一个项目用到了Lua,开发人员对Lua库进行了一层封装,以利于使用。但从封装来看,如果对Lua库本身不了解的话,还是很难使用。我觉得好的封装应该是不用再详细理解原来的库/语言的情况下就能使用,这样的封装才有较大的价值。关于如何在C++中调用Lua函数,我做了自己的封装尝试,很不完整,但思路应该是对的。
template<class RetTuple, class ArgTuple>
struct lua_function
{
lua_function(lua_State * L, const char * f)
: L_(L), f_(f)
{
}
RetTuple operator()(const ArgTuple & at)
{
// step 1
lua_getglobal(L_, f);
// step 2
// 这里需要一个模板函数,能将at中的所有数据
// push到lua栈中,略掉
//step 3
lua_pcall(L_,
boost::tuples::length<ArgTuple>::value,
boost::tuples::length<RetTuple>::value,
0);
// step 4
// 这里需要一个模板函数,能从lua栈中弹出所有
// 的参数, 然后返回,略掉
}
};
举一个例子,使用的时候可以像下面这样调用:
using namespace boost::tuples;
lua_State * L = lua_open();
luaL_dostring(L, "function foo(a) return a*2.0 end")
lua_function<tuple<double, double>, tuple<double> > f(L, "foo");
tuple<double,double> ret = f(tuple<double>(3.5));
暂时没有时间对Lua库进行较完整的封装,以后有时间在做吧。
单体模式:使一个程序里某个对象只能产生一个实例的模式。
它的定义如此简单,以至于看起来实现一个单体模式也是轻而易举的事。但如果读过GoF的《设计模式》和
Andrei Alexandrescu的《Modern C++ Design》以后,大部分人可能都会改变原先过于单纯的想法。它太复杂了,以至于大部分程序员可能都无法给出一个较通用的实现。
实现一个单体模式挑战有(但不局限于)以下几个方面:
1.单体实例生成的时间
2.单体实例的生存期管理
3.单体实例的访问控制
4.单体实例的生成方式
以后的讨论会分析各个方面的挑战,糟糕的是,它们会互相纠缠在一起,并牵扯到其他相关的程序设计问题,很难只谈一个方面而不涉及其他,但尽量给出一个相对串行的脉络。
注:
写这个系列文章的目的不是要和大家探讨如何实现一个大而全的单体模式,而是希望厘清其设计过程的问题,给希望挑战这个模式的程序员一些参考。我对这个模式
的观点是,尽量避免使用它,如果避免不了的话,尽量缩小这个模式的设计需求,并只用在你明确它的使用条件和可能带来的问题的环境下。