isergey
Июль 21, 2010 21:43:37
Друзья, возникла проблема. Есть класс:
class ZConnection{
ZOOM_connection zc;
friend class ZResultSet;
ZOOM_connection _getYazConnection() const {return zc;}
//ZConnection (const ZConnection &);
//ZConnection &operator= (const ZConnection &);
public:
//ZOOM_connection _getYazConnection() const {return zc;}
ZConnection();
ZConnection(const ZOptions *zo);
~ZConnection ();
void connect (const string &hostname, int portnum);
ZResultSet* search(const ZQuery &zq);
};
Который я описал так:
class_<ZConnection>(“ZConnection”)
.def(init<const ZOptions *>())
.def(“connect”, &ZConnection::connect)
.def(“search”, &ZConnection::search, return_internal_reference<>())
;
Дело в том, что когда я возвращаю указатель на объект ZResultSet* из метода search, при удаленнии этого объекта не вызывается его деструктор и происходит утечка памяти.
Если я явно создам объект ZResultSet, то при удалении деструктор вызывается. Что происходит? Может необходимо указать дополнительные параметры при описании класса, для того чтобы объект по указателю удалялся корректно? Спасибо.
Решение:
Проблему удалось решить, поменяв описание метода:
.def(“search”, &ZConnection::search, return_value_policy<manage_new_object>())
isergey
Июль 21, 2010 22:37:23
Наверное это бредовое решение, но я добавил следующий метод:
class_<ZResultSet>(“ZResultSet”)
.def(“__del__”, &ZResultSet::del)
В методе ZResultSet.del явно вызывается деструктор
Андрей Светлов
Июль 21, 2010 23:05:54
какой деструктор, если у вас указан return_internal_reference?
isergey
Июль 21, 2010 23:14:14
Так что же мне делать? Как быть?
isergey
Июль 21, 2010 23:53:18
Таки нашел решение.
.def(“search”, &ZConnection::search, return_value_policy<manage_new_object>())
Андрей Светлов
Июль 21, 2010 23:56:13
Уже лучше. А возвращаемый ZResultSet точно всегда “новый объект”, который создается в search?
isergey
Июль 22, 2010 00:06:38
Да. Собственно вот код:
ZResultSet* ZConnection::search(const ZQuery &zq){
ZResultSet *rs = new ZResultSet(this, zq);
return rs;
}
Возник еще вопрос, а как насчет конструкторов копирования и прочих фишек, касаемых копирования объектов. Нужно ли их описывать в классе или же питон работает только с указателями?
Андрей Светлов
Июль 22, 2010 16:46:32
вообще-то политика по умолчанию в c++ <-> python преобразованиях - именно копирование.
Помимо политик можно указывать wrapper class аргументом шаблона в class_<>.
Вообще же, безотносительно к питону всегда стоит соблюдать несколько простых правил:
1. Для полиморфных объектов следует запретить копирование и присваивание, реализовать виртуальный деструктор.
2. Для неполиморфных нужно либо прописать явно присваивание/копирование, либо явно же их запретить.
Простейший способ запрета - унаследоваться от boost::noncopyable.
isergey
Июль 23, 2010 14:41:05
Андрей, спасибо за Ваши ответы!