Python.boost学习笔记(4)

这一章首先通过一个封装简单的类来讲解如何封装类的constructor, method和data member. 

#include <boost/python.hpp>
#include <iostream>
using namespace boost::python; 

class animal
{
public:
  
  animal()
  {
    myLanguage="";
  };
  animal(std::string language)
  {
    myLanguage=language;
  };
  std::string get()
  {
    return myLanguage;
  }
  std::string myLanguage;
};
BOOST_PYTHON_MODULE(cry)
{
  class_<animal>("animal")
    .def(init<std::string>()) // wrap for multipole constructors
    .def("get",&animal::get)
    .def_readonly("language", &animal::myLanguage); // or set it as def_readwrite, note: for private member, we cannot wrap it here
}

封装类用boost的宏, BOOST_PYTHON_MODULE( module name)开始。 在module内定义需要被封装的部分: class_<被封装类>("module中对应的类的名称")加.def(方法名称, 方法对象)。 对于data member比较特殊,首先一定不能使private的,这个不管你怎么play都不会编译通过 (难道python不支持friend机制?)。 然后用.def_readonly就是不可以修改只可读,相当于const xxx的member,或者def_readwrite, 那么就是可读写。 

编译运行测试:

Python 2.7.5 (default, Nov  3 2014, 14:26:24) 
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cry
>>> a=cry.animal()
>>> b=cry.animal("hello")
>>> print a.get()

>>> print b.get()
hello
>>> a.language
''
>>> b.language
'hello'
>>> b.language='test'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> 

这种wrapper对于一般性的类有效,可惜在GUI下面。。。特别是邪恶的QT这种lib下面却是没什么用。。。。 那么对已C++的继承和多态, python是如何封装的。。。


把上面的例子稍微做修改

#include <boost/python.hpp>
#include <iostream>
using namespace boost::python; 

class animal
{
public:
  
  animal()
  {
    myLanguage="";
  };
  animal(std::string language)
  {
    myLanguage=language;
  };
  std::string get()
  {
    return myLanguage;
  }
protected:
  std::string myLanguage;
};

class dog :public animal
{
public:
  
  dog()
  {
    myLanguage="bak bak";
  };
  dog(std::string language)
    :animal(language)
  {
  };
};

void myCry(animal* it)
{
  std::cout<<it->get()<<std::endl;
}

BOOST_PYTHON_MODULE(cry)
{
  class_<animal>("animal")
    .def(init<std::string>())
    .def("get",&animal::get);
  class_<dog, bases<animal> >("dog")
    .def(init<std::string>());
  def("myCry",myCry);
}

现在有一个叫做dog的类继承animal,他的constructor不同于animal, 有一个 myCry的function来test多态。

class_<dog, bases<animal> >("dog")
    .def(init<std::string>());
只要用bases<animal>, 就不需要再def get了,因为在animal里面已经被def过一次,wrapper自动继承过来。


Python 2.7.5 (default, Nov  3 2014, 14:26:24) 
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cry
>>> a=cry.animal()
>>> b=cry.dog()
>>> myCry(a)
>>> cry.myCry(a)

>>> cry.myCry(b)
bak bak

虚函数是另外一种需要处理的情形。这个wrapper需要从C++wrap一次之后再用boost wrap

那么再做简单的修改:


#include <boost/python.hpp>
#include <iostream>
using namespace boost::python; 

class animal
{
public:
  
  virtual std::string get()
  {
    return "Virtual animal, not implemented";
  }
  virtual ~animal(){};
};

class dog :public animal
{
public:
  virtual std::string get()
  {
    return "bak bak";
  }
  virtual ~dog(){};
};

// wrapper for animal
class animalWrap: public animal,public wrapper<animal>
{
public:
  std::string get()
  {
    if (override get=this->get_override("get"))
      return get();
    return animal::get();
  }
  std::string default_get()
  {
    return this->animal::get();
  }
};

void myCry(animal* it)
{
  std::cout<<it->get()<<std::endl;
}
BOOST_PYTHON_MODULE(cry)
{
  class_<animalWrap,boost::noncopyable>("animal")
    .def("get",&animal::get,&animalWrap::default_get);
  class_<dog, bases<animal> >("dog");
  def("myCry",myCry);
}


现在把get作为虚函数,返回string各不相同。 其中单独写的wrapper:

// wrapper for animal
class animalWrap: public animal,public wrapper<animal>
{
public:
  std::string get()
  {
    if (override get=this->get_override("get"))
      return get();
    return animal::get();
  }
  std::string default_get()
  {
    return this->animal::get();
  }
};


一个继承animal, 一个继承 wrapper<animal>, 第二个是boost给你做好的wrapper, 里面需要implement两个函数, get和default_get, get里面检查是不是有overload,如果是,返回overloaded,不是则返回父类的。至于为什么要一个default_get,我没读懂doc,但是照着做却是work. 有人懂的话告诉我。

在boost wrapper里面两个都要wrap

 class_<animalWrap,boost::noncopyable>("animal")
    .def("get",&animal::get,&animalWrap::default_get);

注意class_后面放的是wrap class name,并且加了个不知为什么的boost::noncopyable, 后面两个我们wrapper里都定义的function都放进去。

编译后在python中定义一个叫做cat的animal的子类,通过myCry来检测是否像预期一样的工作


>>> from cry import *
>>> a=animal()
>>> b=dog()
>>> class cat(animal):
...     def get(self):
...             return "miao miao"
... 
>>> c=cat()
>>> myCry(a)
Virtual animal, not implemented
>>> myCry(b)
bak bak
>>> myCry(c)
miao miao
>>> 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
st_asio_wrapper是一组类,功能是对boost.asio的包装(调试环境:boost-1.50.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步,当然这是从boost.asio继承而来; 自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 1.1版更新内容: 增加了自定义数据模式的支持,可用于st_asio_wrapper server与其它客户端的通信、或者st_asio_wrapper client与其它服务端的通信;当然,两端都是st_asio_wrapper的话,就用透明传输即可(1.0版已经支持了)。 1.2版更新内容: 修复BUG:当stop_service之后,再start_service时,client_base内部某些成员变量可能没有得到复位; 服务端增加修改监听地址功能,当然仍然要在start_service之前调用set_server_addr函数。 1.3版更新内容: 增加自定义消息格式的发送,这个本来是在1.1版本实现的,结果我漏掉了,只实现了自定义消息格式的接收。 1.4版更新内容: 将打包与解包器从client_base分离出来,以简化这个日益复杂的基类; 可以在运行时修改打包解包器。 1.5版更新内容: 增加ipv6支持,默认是ipv4,服务端和客户端都通过设置一个ipv6的地址来开启这个功能; 增加了一些服务端helper函数,小改了一下客户端set_server_addr函数签名(调换了两个参数的位置以保持和服务端一样)。 1.6版更新内容: 增加了接收消息缓存(改动较大,on_msg的语义有所变化,请看开发教程第三篇)。 1.7版更新内容: 修复vc2010下编译错误; 修复默认解包器BUG(同时修改解包器接口); 修复log输出BUG; 更好的包装了服务端类库,现在服务端可以像客户端一样简单的使用了(完全不用继承或者重写虚函数,申请一个对象即可); 结构大调整,类名大调整,请参看开发教程第一篇。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值