Работа с C++ fuzzylite lib и ObjC в iOS (нечеткая логика)
Я забрел в глубокий конец бассейна здесь. Я добился хороших успехов, но сейчас просто бегаю. Я пытаюсь использовать эту библиотеку нечеткой логики в iOS: http://code.google.com/p/fuzzy-lite/
Я получил его для компиляции - я добавил к своему проекту файлы.cpp и.h и изменил суффикс на главном viewController на ".mm". Я могу запустить файл fuzzyLite test.h из viewDidload (см. Ниже). Он запускается и отображаются данные теста.
Что мне нужно сделать, это создать постоянный экземпляр fuzzyLite, чтобы я мог использовать его в своем приложении (например, иметь возможность обратиться к нему, а затем очистить при выгрузке приложения).
Я искал вокруг, но не понял обсуждения / примеры включения кода C++ в проект ObjC. Может кто-нибудь показать мне, как я могу продвинуться вперед с этим - упаковав код fuzzyLite, чтобы я мог вызывать функции и получать результаты обратно? Спасибо!
РЕДАКТИРОВАТЬ: я добился прогресса в этом, используя метод, подробно изложенный здесь: http://robnapier.net/blog/wrapping-c-take-2-1-486
Одна вещь, по которой я неясен, это очистка памяти. Функция dealloc очищает экземпляр обернутого экземпляра CPP - но как насчет памяти, выделенной в экземпляре CCP? Похоже, мне нужно вызвать метод, чтобы освободить его до удаления экземпляра.
пример: у обернутого класса есть несколько экземпляров переменных подклассов - достаточно ли моей функции очистки для правильного управления памятью?
void Bingo::cleanup(){
delete engine;
engine = NULL;
delete health;
health = NULL;
delete energy;
energy = NULL;
}
-заголовок для упакованного класса CPP
#include "fuzzylite/FuzzyLite.h"
namespace fl {
class Bingo {
public:
FuzzyEngine* engine;
OutputLVar* health;
InputLVar* energy;
Bingo();
void Fuzz();
void setInput(float input);
};
}
из обёртки ObjC:
- (void)dealloc
{
delete _cpp;
_cpp = NULL;
[super dealloc];
}
FuzzyLiteIOSViewController.mm
#include "FuzzyLiteIOSViewController.h"
#include "FuzzyLite.h"
#include "test.h"
#include <limits>
#include "fuzzylite/FunctionTerm.h"
//stuff not shown
- (void)viewDidLoad
{
[super viewDidLoad];
fl::Test* test = new fl::Test();
test->SimpleMamdani();
}
test.h
#ifndef FL_TEST_H
#define FL_TEST_H
namespace fl {
class Test {
public:
static void SimpleMamdani();
};
}
#endif /* FL_TEST_H */
test.cpp
#include "fuzzylite/test.h"
#include "fuzzylite/FuzzyLite.h"
#include <limits>
#include "fuzzylite/FunctionTerm.h"
namespace fl {
void Test::SimpleMamdani() {
FuzzyOperator& op = FuzzyOperator::DefaultFuzzyOperator();
FuzzyEngine engine("simple-mamdani", op);
engine.hedgeSet().add(new fl::HedgeNot);
engine.hedgeSet().add(new fl::HedgeSomewhat);
engine.hedgeSet().add(new fl::HedgeVery);
fl::InputLVar* energy = new fl::InputLVar("Energy");
energy->addTerm(new fl::ShoulderTerm("LOW", 0.25, 0.5, true));
energy->addTerm(new fl::TriangularTerm("MEDIUM", 0.25, 0.75));
energy->addTerm(new fl::ShoulderTerm("HIGH", 0.50, 0.75, false));
engine.addInputLVar(energy);
fl::OutputLVar* health = new fl::OutputLVar("Health");
health->addTerm(new fl::TriangularTerm("BAD", 0.0, 0.50));
health->addTerm(new fl::TriangularTerm("REGULAR", 0.25, 0.75));
health->addTerm(new fl::TriangularTerm("GOOD", 0.50, 1.00));
engine.addOutputLVar(health);
fl::RuleBlock* block = new fl::RuleBlock();
block->addRule(new fl::MamdaniRule("if Energy is LOW then Health is BAD", engine));
block->addRule(new fl::MamdaniRule("if Energy is MEDIUM then Health is REGULAR", engine));
block->addRule(new fl::MamdaniRule("if Energy is HIGH then Health is GOOD", engine));
engine.addRuleBlock(block);
for (fl::flScalar in = 0.0; in < 1.1; in += 0.1) {
energy->setInput(in);
engine.process();
fl::flScalar out = health->output().defuzzify();
(void)out; //Just to avoid warning when building
FL_LOG("Energy=" << in);
FL_LOG("Energy is " << energy->fuzzify(in));
FL_LOG("Health=" << out);
FL_LOG("Health is " << health->fuzzify(out));
FL_LOG("--");
}
}
1 ответ
В принципе невозможно ответить на ваш вопрос, учитывая предоставленную информацию. Ваш вопрос о cleanup
метод Bingo
класс, но экземпляры Бинго (ни в стеке, ни в куче) нигде не встречаются в ваших фрагментах кода. Точно так же вы заявляете, что очищаете "обернутый экземпляр CPP", но на него больше нигде не ссылаются. Похоже , что у вас есть утечки в вашем Test::SimplMamdani
метод - ты new
куча объектов, которые [по крайней мере, в раскрытом коде] не имеют соответствующих delete
s. Точно так же в вашем FuzzyLiteIOSViewController::viewDidLoad
метод, который вы создаете Test
экземпляр в кучу без соответствующего delete
, Я предполагаю, что в вашем коде на C++ не происходит ничего от autoptr.
ОБНОВЛЕНО для предоставления дополнительной информации:
Исходя из вашего комментария, вам нужно пересмотреть базовую структуру языка C++. Основное правило заключается в том, что вам нужно delete
все, что вы new
, Очистить для Bingo
класс должен быть выполнен в деструкторе (конструкция C++ для Objective-C dealloc
). Ваш Bingo
класс должен выглядеть примерно так:
Bingo.h:
namespace fl {
class Bingo {
public:
Bingo();
virtual ~Bingo();
void Fuzz();
void setInput(float input);
FuzzyEngine* engine;
OutputLVar* health;
InputLVar* energy;
protected:
private:
};
}
Bingo.cpp:
using namespace fl;
Bingo::Bingo() {
}
Bingo::~Bingo() {
if (engine) {
delete engine;
}
if (health) {
delete health;
}
if (energy) {
delete energy;
}
}
Когда ты delete
экземпляр Бинго, деструктор будет вызван и Bingo
переменные-члены будут удалены.
Возможно, ваши переменные-члены (двигатель, здоровье и энергия) должны быть частными по объему и отображаться через общедоступные методы получения и установки.
Возьмите копию справочника Бьярна Страуструпа по С ++ и быстро его изучите, или воспользуйтесь онлайн-руководством по настройке, подобным этому.