C++混合編程之idlcpp教程Python篇(7)

上一篇在這 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用來計數圓的面積便可,最終使用時腳本插件會找到對應函數進行調用。

編譯執行,結果以下圖:

 

相關文章
相關標籤/搜索