上一篇在這 C++混合編程之idlcpp教程Python篇(6)html
第一篇在這 C++混合編程之idlcpp教程(一)python
與PythonTutorial4工程類似,工程PythonTutorial5中,一樣加入了四個文件:PythonTutorial5.cpp, Tutorial5.cpp, Tutorial5.i, tutorial5.py。其中PythonTutorial5.cpp的內容基本和PythonTutorial4.cpp雷同,再也不贅述。首先看一下Tutorial5.i的內容:編程
#import "../../paf/src/pafcore/Reference.i" ###include <vector> namespace tutorial { struct Point { float x; float y; Point(); Point(float a, float b); nocode Point(const Point& pt); }; override class Shape : Reference { override abstract float getArea(); ## virtual ~Shape() {} }; class ShapeManager(value_object) { void addShape(Shape* shape); float getTotalArea(); static ShapeManager* GetInstance(); #{ ~ShapeManager(); private: std::vector<Shape*> m_shapes; #} }; class Triangle : Shape { Point m_vertices[#3]; nocode Triangle(); ##virtual float getArea(); }; }
與Tutorial4.i相比,大部份內容是同樣的,不一樣之處在於類型Shape的聲明以及其下的純虛函數getArea;ide
override class Shape : Reference函數
override abstract float getArea();spa
在這兩處聲明的最前面都多了一個關鍵字override。意味着能夠在腳本代碼中寫一個類型,讓它「派生」自Shape,而且可以「重寫」虛函數getArea。固然其實是經過idlcpp生成的一個派生類配合腳本插件代碼來完成相似的任務。經過在類型的聲明class 前加上關鍵字override 表示此類型能夠被腳本「派生」,在虛函數聲明的關鍵字virtual 或 abstract前加上關鍵字override表示此虛函數能夠被腳本「重寫」。插件
在宿主語言和腳本的混合使用中,一個常見的用法是在宿主語言中根據必定的條件向外發出事件,而用腳本語言來編寫事件處理代碼,例如在WOW中用一個XML文件描述GUI界面,同時註明事件處理函數對應的Lua函數名。idlcpp提供的腳本繼承C++類而後重寫虛函數的功能能夠很好的實現相似的需求。code
編譯後生成的Tutorial5.h的內容以下:htm
//DO NOT EDIT THIS FILE, it is generated by idlcpp //http://www.idlcpp.org #pragma once #include "../../paf/src/pafcore/Typedef.h" #include "../../paf/src/pafcore/Reference.h" #include <vector> namespace tutorial { struct Point { public: float x; float y; Point(); Point(float a,float b); }; class Shape : public pafcore::Reference { public: static ::pafcore::ClassType* GetType(); virtual ::pafcore::ClassType* getType(); virtual size_t getAddress(); virtual float getArea() = 0 ; virtual ~Shape() {} }; class ShapeManager { public: void addShape(Shape* shape); float getTotalArea(); static ShapeManager* GetInstance(); ~ShapeManager(); private: std::vector<Shape*> m_shapes; }; class Triangle : public Shape { public: static ::pafcore::ClassType* GetType(); virtual ::pafcore::ClassType* getType(); virtual size_t getAddress(); Point m_vertices[3]; virtual float getArea(); }; }
這裏生成的代碼和Tutorial4.h基本一致。最後看一下Tutorial5.py的內容對象
import pafpython;
paf = pafpython.paf;
Circle = {} Circle.__index = Circle; function Circle.New() circle= {radius = 1.0} setmetatable(circle, Circle); circle.shape = paf.tutorial.Shape._inherit_(circle); return circle; end function Circle:getArea() return self.radius * self.radius * 3.1415926; end circle = Circle.New(); circle.radius = 2.0; shapeManager = paf.tutorial.ShapeManager.GetInstance(); shapeManager:addShape(circle.shape); print(shapeManager:getTotalArea()._); triangle = paf.tutorial.Triangle(); triangle.m_vertices[0] = paf.tutorial.Point(0,0); triangle.m_vertices[1] = paf.tutorial.Point(0,1); triangle.m_vertices[2] = paf.tutorial.Point(1,1); shapeManager:addShape(triangle); print(shapeManager:getTotalArea()._);
在上面的代碼中,寫了一個類型Circle。在函數Circle.New 經過下面這一行
circle.shape = paf.tutorial.Shape._Derive_(circle);
來模擬繼承,語法:C++類型._Derive_(腳本對象) 用於完成模擬繼承的行爲。實際上circle.shape纔是C++類型Shape的派生類實例的引用,在C++中須要用到Shape類型的地方,將circle.shape傳遞過去便可,以下面的使用方式。
shapeManager:addShape(circle.shape);
而後在類型Circle中提供一個與C++基類同名的函數getArea用來計數圓的面積便可,最終使用時腳本插件會找到對應函數進行調用。
編譯執行,結果以下圖: