对operator new的封装

最近想用做一种C++ Script,来分离引擎和游戏,AI就可以完全用这种C++ Script来做,不需要牵涉到任何引擎的代码,只是使用引擎暴露的API,这样做的好处很多,最重要的就是可以只依赖于API,减少了高层逻辑和底层引擎的耦合,当然,这样的结构就需要引擎提供一套完备的API接口。在接口中,由于是还是使用C++,对内存操作的接口就不可避免,因此就引出了我今天想说的这个话题。

对这个接口我们有几个要求,首先,不使用new操作符(虽然可以重载new或者placement new,但我们希望我们的API接口格式统一,比如都用函数,或类),还有提供和new一样的完备操作。我一开始写了个最简单的做法:

template<typename T>
T* MEM_New()
{
return new T;
}

对于类Test,在C++Script里可以这样使用这个接口:

Test *pT = MEM_New<Test>();

但这样做有一个最大的问题,就是在C++Script里的类只能用默认构造函数生成实例了,这显然限制了高层的代码,会用起来很不爽(当然,你也可以和GPP程序员说,你只能这么用)。要没限制的话,第一个想到的,就是用宏:

#define MEM_New(ctor)      new ctor

Test *pT = MEM_New(Test());

这样的的做法,可以解决问题,不过,这和直接提供new没什么区别了,不符合设计思想,最近在看Reflection的相关实现,受到启发,我想到了一种方式,可以比较完美的解决这个问题,还是回到模板的思路上来:

template<typename T>
T* MEM_New()
{
return new T;
}

template<typename T, typename P1>
T* MEM_New(const P1& p1)
{
return new T(p1);
}

template<typename T, typename P1, typename P2>
T* MEM_New(const P1& p1, const P2& p2)
{
return new T(p1, p2);
}

这里我写了无参数,一个参数,两个参数的MEM_New版本,可以支持,0个到2个参数的构造函数形式,可以照着这个写法写出支持任意多个参数的API版本,一般写到10个以上就够用了,没人会写超过10个参数的构造函数吧。

当然,在Script里使用起来也很简单,假设我们的Test类有三个构造函数,一个是没参数的,一个是带一个int,还有一个是带一个int,一个const char*,在C++Script里就是这样:

Test *pT0 = MEM_New<Test>();
Test *pT1 = MEM_New<Test>(7);
Test *pT0 = MEM_New<Test>(8, “Hello”);

我觉得,挺完美,欢迎留言讨论。

————————————————————————
作者:Finney
Blog:AI分享站(http://www.aisharing.com/)
Email:finneytang@gmail.com
本文欢迎转载和引用,请保留本说明并注明出处
————————————————————————

(已被阅读1,948次)

4 评论

发表评论

邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Copyright © 2011-2020 AI分享站    登录