Проблемы с утечками или «незарегистрированным классом» при возврате указателей на производные объекты в luabind

Я представляю внутренности моего приложения Lua через luabind, где в C ++ у меня есть Container из shared_ptr<Item> где Item абстрактный базовый класс Производные классы включают ItemA а также ItemB,

Чтобы представить их luabind, я использую пару классов-оболочек (поскольку я хочу, чтобы у контейнера был другой механизм редактирования в интерфейсе скрипта). Я хочу иметь возможность перечислять элементы в контейнере в сценарии Lua, например:

container=app.container
for i,event in ipairs(container.items) do
print(tostring(event))
end

Проблемы, которые у меня есть, состоят в том, что я могу предоставить эту функциональность, возвращая необработанные указатели ItemWrappers, но это приводит к утечке памяти как ItemWrapper деструкторы никогда не называются. Если я попытаюсь объявить оболочки в luabind как умные указатели как описано в документации тогда это бросает «Попытка использовать незарегистрированный класс» исключение, когда я пытаюсь вернуть умный указатель как объект lua.

Оболочки определяются следующим образом:

class ContainerWrapper {
public:
ContainerWrapper(Container& c) : container(c) {};
Container&  c;  // reference to the actual container
};

class ItemWrapper {
public:
virtual ~ItemWrapper() {};
ItemWrapper(int itemIndex_) : itemIndex(itemIndex_) {};
int   itemIndex;  // items are addressed by index
};

class ItemAWrapper : public ItemWrapper {
public:
ItemAWrapper(int itemIndex_) : ItemWrapper(itemIndex_) {};
};

Регистрация luabind выглядит следующим образом: (если я не использую умные указатели)

class_<ItemWrapper>("Item") ,
class_<ItemAWrapper, ItemWrapper>("ItemA")

и так, если я делаю:

class_<ItemWrapper, std::tr1::shared_ptr<ItemWrapper> >("Item") ,
class_<ItemAWrapper, ItemWrapper, std::tr1::shared_ptr<ItemWrapper> >("ItemA")

Функция выставить items член Container возвращает таблицу lua:

luabind::object Container::getItemsAsTable(lua_State* L)
{
luabind::object table=luabind::newtable(L);
for (int i=0; i<items.size(); i++) {
table[i+1]= new ItemAWrapper(); // or function to return pointer/smart pointer
}
return table;
}

Это правильный способ установки значения в таблице? Это присваивание генерирует исключение, если я передаю умный указатель, но если я передаю необработанный указатель, то кажется, что он не присваивает его внутреннему умному указателю, и объект пропускается. Сбор мусора тоже не помогает.

0

Решение

Луа уже полиморфный. Так что ваши getItemsAsTable функция не должна new эти ItemWrapper объекты. Просто вставьте в это ценности. Как это: table[i+1] = ItemAWrapper(), Если что-то не происходит, где вы необходимость использовать указатель (например, если изменение таблицы Lua должно быть отражено в C ++), не беспокойтесь. Просто используйте значение.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]