技术开发 频道

CLR开发商业3D游戏引擎实践(一)

       我们准备用CLRC++底层引擎进行一次包装,完成一个中层游戏引擎。察看CLR工程代码,翻阅CLR文档,我们发现LipmanC++基础上对CLR 注入了很多新东西,下面我来先简单熟悉一下CLR

 

       CLR我们关心的部分:

 

       一.琳琅满目的关键字

 

       vs2005集成环境中翻开CLR代码,我们会发现语法加亮了很多以前C++少见的关键字,比如gcnew,ref,value,override,for each,nullptr,#using “xxx.dll”,property,event,delegate等等。这些关键字很多引入了诸如垃圾回收,属性,事件,代理等CLR语言天生支持的特性。其实在C++中,这些新特性大多都有自己的一些实现模式,现在它已经作为语言的直接支持出现了。在很多情况下,它们都能付出很小代价的前提下,解决各种问题。

 

       古怪的上尖括号^CLR操作的不是地址指针,而是句柄。^就是用来申明句柄类型的关键字,T^ p=gcnew T;这样的语法,就是产生了一个T类型的句柄。句柄这东西简单的也可以就把它考虑成为一类指针。通过句柄,我们可以访问到CLR对象,但是由于GC机制的存在,地址是可变的。为了应付变化的地址,CLR对应的提供了pin_ptr关键字,可以用钉子暂时钉死clr的变量地址。这个在C++/CLR混合编码的时候经常需要用到。

 

       gcnew::托管对象分配,跟C++new 一样,负责分配内存和构造对象。不同的是,它分配在托管堆上。同时用户不再需要去关心什么时候调用delete来释放。

 

       ref&value:申明一个托管类定义时,我们必须声明或者ref或者value,以告诉编译器,这不是一个C++类。绝大部分托管类都是ref类,value类相对于ref类来说,它适合一些很小型的对象的申明,这样的对象允许在栈中产生,但是它的限制也很多,复杂的构造器就是它所不能承受的。

 

overrideC++申明一个虚拟成员函数的时候,通常如下:

 

       virtual void func();

 

       而在CLR中当重载父类虚方法的时候,编译器会抱怨没有告诉它这个函数要重载还是新写。这时候需要用如下语法来告诉编译器:

 

       virtual void func() override/new;

 

       for each:和明显这是类似stlfor_each迭代。

 

nullptr:无效的句柄,这个可以理解为c++里面的空指针。任何对nullptr句柄的访问,都会产生CLR异常。

 

#using “xxx.dll”:导入了clr动态库的符号表,这个对封装非常有用,它可以最大限度的降低不必要的头文件暴露,降低工程耦合度。

 

property:属性,这是一个原来在大多数C++编译器厂商都有自己规格的支持的特性,但是始终没有被纳入标准C++

 

property System::String ^ Text{

 

                System::String ^ get();

 

                void set(System::String ^);

 

        }

 

    这是CLR的一个属性的申明,和以前C++Builder及其类似,它可以为类对象提供一个看起来像操作成员变量一样的语法,但真实的操作确是一个复杂的函数流程。getset可以隐含技术细节,对外暴露的接口非常简洁明快。但是,我有一个小小的遗憾,CLRpropertyset方法没有返回值,在写连等的时候无法编译通过。例如:

 

var1.Text=var2.Text=Hello World;

 

我想如果set可以申明成 T% set(T^);开发者在setreturn *this;这个问题也就可以解决了。(%CLR的取地址符-!-

 

event&delegate

 

       public delegate void OnSubActionFinished( System::String^ Act , int userdata );

 

    上面的语法可以申明一个代理原形。

 

    event OnSubActionFinished^      SubActionReporter;

 

    这个可以申明一个事件。

 

       此后,我们只要完成一些OnSubActionFinished同型的函数,让事件SubActionReporter+=任意个此类函数,当我们call这个SubActionReporter的时候,所有被+=的函数,都会接受到事件通知。

0
相关文章