• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            馭風(fēng)萬(wàn)里無(wú)垠

            用Boost.Python + CMake + wxPython構(gòu)建跨語(yǔ)言GUI程序<三>

            • Class Exposition

            類(lèi)是OO編程關(guān)于封裝的基本單元,圍繞其相關(guān)的主要是虛函數(shù)、成員變量、成員函數(shù)、構(gòu)造、析構(gòu)、繼承、多態(tài)的問(wèn)題。

            本示例新建于一個(gè)ExposeClass的子項(xiàng)目目錄,并且生成expose_class.so這個(gè)模塊庫(kù)。

            前邊已經(jīng)穿插了一些基本的使用方法,下邊是一些更復(fù)雜的東西。

            1> 構(gòu)造函數(shù)重載和數(shù)據(jù)成員、屬性

            c++里邊運(yùn)行聲明多個(gè)構(gòu)造函數(shù),并且一旦用戶聲明一個(gè),編譯器不再生成默認(rèn)構(gòu)造函數(shù);對(duì)于數(shù)據(jù)成員有簡(jiǎn)單的public/private/protected三種訪問(wèn)權(quán)限控制,以及很多人采用的getter/setter來(lái)模擬的屬性接口。對(duì)于構(gòu)造函數(shù)重載,只需要多聲明幾個(gè)init函數(shù)即可,對(duì)于屬性和數(shù)據(jù)成員,可如下施為:

            ///////////////////////////////////////////////////////////////////////////////
            struct World
            {
                //Constructors
                World(int i){ this->msg = "int parameter";}
                World(std::string msg) {this->msg = msg;} 
            
                //Simple interface
                void set(std::string msg) { this->msg = msg; }
                std::string greet() { return msg; }
                std::string msg;
                //Data variable
                int name;
                int value;
                //Property
                std::string getProp() {return prop;}
                void setProp(const std::string& val) {prop = val;}
            private:
                std::string prop;
            };
            

            上述的類(lèi)可如下導(dǎo)出:

            BOOST_PYTHON_MODULE(expose_class)
            {
                class_<World>("World", init<std::string>())
                    .def(init<int>())
                    .def("greet", &World::greet)
                    .def("set", &World::set)
                    .def_readonly("name", &World::name)
                    .def_readwrite("value", &World::value)
                    .add_property("roprop", &World::getProp)
                    .add_property("prop", &World::getProp, &World::setProp)
                    ;

            上邊的init模板函數(shù)用于制定額外的構(gòu)造函數(shù)。

            read_only指定對(duì)應(yīng)的name成員為只讀,read_write則說(shuō)明對(duì)應(yīng)的value是可讀寫(xiě)的數(shù)據(jù)成員。

            add_property則添加一個(gè)對(duì)應(yīng)名字的Python熟悉,第一個(gè)參數(shù)為get方法的接口,第二個(gè)為set方法接口,如果只有一個(gè)被提供,那么對(duì)應(yīng)的就是一個(gè)只讀屬性。

            調(diào)用例子如下:

            >>> import expose_class as cls
            >>> cls.World("str")
            <expose_class.World object at 0x7f3e29529e10>
            >>> cls.World(124)
            <expose_class.World object at 0x7f3e29529d60>
            >>> obj=_
            >>> obj.name="name"
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            AttributeError: can't set attribute
            >>> obj.name
            1
            >>> obj.value="value"
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            Boost.Python.ArgumentError: Python argument types in
                None.None(World, str)
            did not match C++ signature:
                None(World {lvalue}, int)
            >>> obj.value=12
            >>> obj.roprop="name"
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            AttributeError: can't set attribute
            >>> obj.roprop
            ''
            >>> obj.prop = "name"
            >>> obj.name
            1
            >>> obj.value
            12
            >>> 

            上邊例子中,企圖對(duì)read_only的變量或者屬性進(jìn)行賦值的時(shí)候均發(fā)生異常而報(bào)錯(cuò)。

            2> 抽象類(lèi)

            所謂的抽象類(lèi)意指其構(gòu)造函數(shù)不能被外部調(diào)用,需要通過(guò)factory method來(lái)返回一個(gè)多態(tài)的指針,指向構(gòu)造的子對(duì)象。

            下邊是個(gè)簡(jiǎn)單的抽象類(lèi)的例子:

            ///////////////////////////////////////////////////////////////////////////////
            //Abstract class
            struct Abstract
            {
                static std::string msg;
                void set(std::string msg) { this->msg = msg; }
                std::string greet() { return msg; }
            
                static Abstract* CreateInstance()
                {
                    return new Abstract();
                }
            };
            
            std::string Abstract::msg = "default value";

            導(dǎo)出的情況如下:

            class_<Abstract>("Abstract", no_init)
                .def("greet", &Abstract::greet)
                .def("set", &Abstract::set)
                ; 

                 def("CreateAbstract", Abstract::CreateInstance,
                         return_value_policy<manage_new_object>());

            這里的no_init就是指定沒(méi)有構(gòu)造函數(shù)可調(diào)用。

            >>> import expose_class as test
            >>> test.Abstract()
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            RuntimeError: This class cannot be instantiated from Python
            >>> obj=test.CreateAbstract()
            >>> obj.greet()
            'default value'

            調(diào)用的時(shí)候,如果調(diào)用了這個(gè)Abstract的構(gòu)造,就會(huì)拋出異常。對(duì)于factory method,由于返回的對(duì)象是函數(shù)內(nèi)部構(gòu)造于堆上的,因此用return_value_policy顯示的指明其生存期。

            3> 繼承和虛函數(shù)

            虛函數(shù)是c++實(shí)現(xiàn)多態(tài)機(jī)制和OO動(dòng)態(tài)的核心所在,這里主要關(guān)注兩種情況,一種是純虛函數(shù)(強(qiáng)制之類(lèi)提供自己的實(shí)現(xiàn)),一種是基類(lèi)提供了默認(rèn)實(shí)現(xiàn)的普通虛函數(shù)。

            對(duì)于繼承而言,必須通過(guò)一個(gè)wrapper類(lèi)來(lái)告知boost.python各個(gè)類(lèi)之間的繼承關(guān)系。

            純虛函數(shù)和一般虛函數(shù)的區(qū)別僅僅是沒(méi)有默認(rèn)實(shí)現(xiàn),在導(dǎo)出的時(shí)候,一般虛函數(shù)要多提供一個(gè)基類(lèi)默認(rèn)實(shí)現(xiàn)的函數(shù),而純虛函數(shù)需要特別修飾聲明一下。

            參考下邊這兩個(gè)類(lèi):

            ///////////////////////////////////////////////////////////////////////////////
            //Inheritance
            struct Base 
            {   
                virtual ~Base() {}; 
            
                //Virtual interface
                virtual int fun() = 0;
            
                virtual int func1(int i)
                {
                    cout << "Default implementtion of func1" << endl;
                    return 0;
                }
            };
            
            struct Derived : Base
            {
                virtual int fun()
                {
                    cout << "Derived implementation of fun!" << endl;
                    return 0;
                }
            
                virtual int func1(int i)
                {
                    cout << "Derived implementation of func1!" << endl;
                    return 0;
                }
            };
            
            接下來(lái)需要聲明一個(gè)wrapper類(lèi)作為基礎(chǔ)來(lái)導(dǎo)出,告知基類(lèi)信息。這里用了兩個(gè)函數(shù),一個(gè)是純虛函數(shù)fun, 一個(gè)是普通虛函數(shù)func1.
            對(duì)于純虛函數(shù),只需要通過(guò)get_override得到具體的函數(shù)對(duì)象并調(diào)用即可(因?yàn)榛?lèi)沒(méi)有實(shí)現(xiàn));
            對(duì)于純虛函數(shù),則要根據(jù)get_override的結(jié)果決定是否是基類(lèi),然后分別調(diào)用對(duì)應(yīng)的函數(shù)。
            具體的wrapper代碼如下:
            
            struct BaseWrap : Base, wrapper<Base>
            {
                //pure virtual implementation
                int fun()
                {
                    return this->get_override("fun")();
                }
            
                //pure virtual with default implementation
                int func1(int i)
                {
                    if (override f = this->get_override("func1"))
                    {
                        return f(i);
                    }
                    else
                        return Base::func1(i);
                }
                int default_func1(int i) {return Base::func1(i);}
            };
            導(dǎo)出的代碼:
                class_<BaseWrap, boost::noncopyable>("Base")
                    .def("fun", pure_virtual(&Base::fun))
                    .def("fun1", &Base::func1, &BaseWrap::default_func1)
                    ;
                class_<Derived, bases<Base> >("Derived");

            這里在導(dǎo)出Derived的時(shí)候,直接用bases模板參數(shù)告知Boost.python它是Base的之類(lèi)(不是BaseWrap的)。

            4> Factory method

            對(duì)于缺乏virtual contructor機(jī)制的c++來(lái)說(shuō),F(xiàn)actory method是一個(gè)很常用的生成之類(lèi)對(duì)象的構(gòu)造方法,如下(為簡(jiǎn)單起見(jiàn),只生成一個(gè)之類(lèi)對(duì)象):

            //Free functions on polymophism
            void baseFunc(Base* ptr)
            {
                ptr->fun();
                ptr->func1(1);
            }
            
            void derivedFunc(Derived* ptr)
            {
                ptr->func1(2);
            }
            
            Base* factoryMethod() { return new Derived; }

            這里也導(dǎo)出這個(gè)接口:

                class_<Derived, bases<Base> >("Derived");
                def("baseFunc", baseFunc);
                def("derivedFunc", derivedFunc);
                def("factoryMethod", factoryMethod,
                        return_value_policy<manage_new_object>());

            調(diào)用的例子:

            >>> base_obj=test.Base()
            >>> dev_obj=test.Derived()
            >>> base_obj.fun()
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            RuntimeError: Pure virtual function called
            >>> dev_obj.fun()
            Derived implementation of fun!
            0
            >>> base_obj.fun1(1)
            Default implementtion of func1
            0
            >>> dev_obj.fun1(1)
            Derived implementation of func1!
            0
            >>> poly_obj=test.factoryMethod()
            >>> test.baseFunc(poly_obj)
            Derived implementation of fun!
            Derived implementation of func1!
            

            posted on 2009-08-10 21:33 skyscribe 閱讀(1097) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            <2009年8月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(3)

            隨筆分類(lèi)

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            亚洲欧美成人久久综合中文网 | 99久久国产免费福利| 2021最新久久久视精品爱| 国产免费久久久久久无码| 国产精品99久久精品| 久久国产免费观看精品3| 亚洲中文字幕无码久久精品1 | 久久免费美女视频| 热久久这里只有精品| 亚洲国产精品一区二区久久| 国产一区二区精品久久| 人人狠狠综合久久亚洲88| 国产99久久久国产精品~~牛| 岛国搬运www久久| 亚洲国产日韩欧美久久| 要久久爱在线免费观看| 人妻无码αv中文字幕久久琪琪布| 午夜人妻久久久久久久久| 九九久久自然熟的香蕉图片| 7国产欧美日韩综合天堂中文久久久久 | 国产成人精品白浆久久69| 99久久精品无码一区二区毛片| 欧美国产精品久久高清| 人妻久久久一区二区三区| 久久综合狠狠综合久久激情 | 无码任你躁久久久久久老妇| 亚洲综合伊人久久大杳蕉| 久久九九有精品国产23百花影院| 久久人人爽人人爽人人片AV麻豆| 狠狠精品久久久无码中文字幕 | 深夜久久AAAAA级毛片免费看| 无码国内精品久久人妻| 亚洲精品高清久久| 2021最新久久久视精品爱| 亚洲欧美日韩精品久久| 亚洲人成无码网站久久99热国产| 亚洲第一极品精品无码久久| 久久精品成人欧美大片| 精品久久久久中文字幕日本 | 亚洲精品久久久www| 国产精品久久久久影院嫩草 |