How can I properly initialize C++ objects within an Arduino program? - c++

In my simple Arduino project, in order to keep things tidy, I decided to create a "Mode Manager" that will handle passing between one mode and another. The basic concept is that each time I want to change the mode, then it will instantiate the next mode and replace the previous one.
Please note that I have 12+ years experience in OOP and Java / Scala, but no experience whatsoever in C++, just the stuff needed to make an Arduino do its stuff without too many structures.
With some studying I managed to create the following "interface" structure:
File: modes/ModeManager.h. This should keep a reference to the current mode, and delegate to it the looping and instantiating the next mode (each mode will know which is the next in line)
#ifndef __MODE_MANAGER__
#define __MODE_MANAGER__
#include <stdint.h>
#include "modes/Mode.h"
class ModeManager {
private:
Mode *mode;
public:
ModeManager();
~ModeManager() {};
virtual void loop(uint8_t voltage);
};
#endif
File: modes/Mode.h is the actual "mode" that runs the real loop function of the program. It also handles instantiating the next mode
#ifndef __MODE__
#define __MODE__
#include <stdint.h>
class Mode {
public:
Mode() {}
virtual ~Mode() {}
virtual void loop(uint8_t voltage) = 0;
virtual void getNext(Mode * target) = 0;
};
#endif
File: modes/ModeManager.cpp
#include "ModeManager.h"
#include <stdint.h>
#include <Arduino.h>
#include "modes/Mode.h"
#include "modes/DummyMode.h"
#define VOLTAGE_NEXT_MODE 5
ModeManager::ModeManager() {
DummyMode cmode = DummyMode();
mode = & cmode; // I'm not sure how this should actually be done
}
void ModeManager::loop(uint8_t voltage) {
if (voltage == VOLTAGE_NEXT_MODE) {
Serial.println("Switching to next mode");
mode->getNext(mode);
} else {
Serial.println("Calling mode loop");
mode->loop(voltage); // From here, nothing.
}
}
File: modes/DummyMode.h
#ifndef __DUMMY_MODE__
#define __DUMMY_MODE__
#include "modes/Mode.h"
class DummyMode : public Mode {
public:
DummyMode();
~DummyMode() {}
virtual void loop(uint8_t voltage);
virtual void getNext(Mode * target);
};
#endif
File: modes/DummyMode.cpp
#include "modes/DummyMode.h"
#include <Arduino.h>
DummyMode::DummyMode() {
Serial.println("Initialization of dummy mode");
}
void DummyMode::loop(uint8_t voltage) {
Serial.print("Voltage: ");
Serial.println(voltage);
}
void DummyMode::getNext(Mode * target) {
DummyMode nextMode = DummyMode();
target = &nextMode;
}
and finally my main.cpp
#include <Arduino.h>
#include "modes/ModeManager.h"
#include "modules/memory.h"
#include "modules/monitor.h"
ModeManager * modeManager;
void setup() {
pinMode(A0, INPUT);
Serial.begin(9600);
Serial.println("Init");
ModeManager mm = ModeManager();
modeManager = & mm;
}
void loop(void) {
uint8_t voltage = map(analogRead(A0), 0, 1024, 0, 5);
modeManager->loop(voltage);
}
Now, theoretically I see no reason why this should not work. In practice I'm 99.9% sure I am doing something wrong with initializations and pointers.
When I try to run this code, I get the following serial out:
Init
Initialization of dummy mode
Calling mode loop
Which means that it freezes at the first iteration of the loop, right before calling mode->loop(voltage);
Can anyone point me in the right direction? Again, I have really no experience of C++, and my knowledge of how to make this structure came from various online resources of C++ programming, including some answers here so please bear with me

Here:
DummyMode cmode = DummyMode();
you are creating a DummyMode instance cmode with automatic lifetime (commonly referred to as on the stack).
You then take the address and assign that to another variable:
mode = & cmode; // I'm not sure how this should actually be done
Since cmode is an object with automatic lifetime it will be destroyed when the program leaves the scope in which it was created. As a result the pointer stored in mode will be dangling and referring to an object that no longer exists. Dereferencing it will trigger undefined behaviour.
It looks like your intention is to create the object with dynamic lifetime.
You can do that with the following:
mode = new DummyMode();
Though then you are responsible for ensure the object is destroyed when it is no longer needed.
That would be done with delete:
delete mode;
In more idiomatic/modern C++ it is typically to use smart pointers to manage the lifetime of such objects and not manually call delete. I see that C++'s standard library is not available for Arduino, but there does seem to be a smart pointer available: https://www.arduino.cc/reference/en/libraries/arxsmartptr/
I would recommend having a good look at using that to have a much easier time avoiding memory leaks.

Related

Arduino: undefined reference to `Class::attribute'

I am developing a library Button to handle some functions of buttons and a class ButtonManager handling the query of the states of those buttons. I don't want to have to create an object for the ButtonManager class so I figured I had to use the static keyword for every attribute and method. In addition I am using a third party library to handle timer interrupts which needs a static function as a parameter.
When I try to compile my code, I get the undefined reference to 'ButtonManager::head' error.
My ButtonManager.h looks like this:
#ifndef BUTTON_MANAGER_H
#define BUTTON_MANAGER_H
#include <Arduino.h>
#include "Button.h"
#include "TimerOne.h"
struct ButtonListItem {
Button* button;
ButtonListItem* next;
};
class ButtonManager {
public:
static ButtonListItem* head = NULL;
static void begin();
static void addButton(Button* newButton);
static void handleButtons();
};
#endif
And the ButtonManager.cpp file looks like this:
#include "ButtonManager.h"
void ButtonManager::begin() {
Timer1.initialize(100000);
Timer1.attachInterrupt(ButtonManager::handleButtons); // handleButtons every 0.1 seconds
}
void ButtonManager::addButton(Button *newButton) {
ButtonListItem* link = new ButtonListItem;
link->button = newButton;
link->next = ButtonManager::head;
ButtonManager::head = link;
}
void ButtonManager::handleButtons() {
ButtonListItem* buttonPtr = ButtonManager::head;
while (buttonPtr != NULL) {
buttonPtr->button->handleButton();
buttonPtr = buttonPtr->next;
}
}
I really don't get what is wrong about this implementation. Is it even the right approach?
I'd appreciate any help and tips how to improve my code.
static ButtonListItem* head = NULL;
If you want to use static data members you must also define them. Declaration of such a member is not a definition.
Put this line at the top of your .cpp file (below #include):
ButtonListItem* ButtonManager::head = NULL;
You may need to also remove = NULL from the declaration in the header. Initialization should be done with the definition.
As for other things you should provide some way to clear the list of buttons. Currently there is no way to de-allocate memory allocated with:
ButtonListItem* link = new ButtonListItem;
(and possibly also memory occupied by the Buttons themselves if no other party is to own that memory). Whenever you use new there should be corresponding delete. And even though for your application it may not matter (static head lives till the end of the execution) this is a good practice to apply proper de-allocation always.

C++ object method calling methods from another class that includes it's

First of all, sorry for the title. I didn't know exactly how to give name to the situation I'm facing.
I am developing a project in C++ that will run over QNX (so answers that recur to Windows libraries are not good).
I have one class that holds and manipulates all my data, and a few other classes that are responsible for dealing with my UI.
The UI manipulating classes include my data class, and when they are initialized, they all get a pointer to the same data object (each one uses different parts of it, though). And the normal flow of the program is the UI receiving events from the user, and then making calls to the data class and updating itself, according to the data class replies. That all works just fine.
The problem is, sometimes it might happen that this data class object receives calls from other sorts of external events (let's say a call from a class responsible for communication), asking it to change some of it's values. After doing so, it would have to update the UI (thus, having to make a call to the UI classes).
The actual objects to all the classes (UI and data) are contained by the "main" class. But as the UI classes include the data class to be able to call it's methods, the data class including UI classes in order to be able to call their methods would fall into mutual inclusion.
The problem resumes, in a very simplistic way (I am just trying to give a visual example of the information flow), to something like this:
main.cpp
#include "interface.h"
#include "data.h"
Data data_;
Interface interface_;
// Initialize all data from files, etc
data_.Init();
// Call the interface that will use all of this data
interface_.Init(&data_);
while(1);
interface.h
#include "data.h"
class Interface
{
Data *data_;
void Init(Data *data);
void ReceiveEvent();
void ChangeScreen (int value);
};
interface.cpp
#include "interface.h"
void Interface::Init(Data *data)
{
// Get the pointer locally
data_ = data;
}
// Function called when a (for example) a touch screen input is triggered
void Interface::ReceiveEvent()
{
ChangeScreen(data_->IncreaseParam1());
}
void Interface::ChangeScreen (int value);
{
// Set the value on screen
}
data.h
class Data
{
int param 1;
void Init();
int IncreaseParam1();
void ReceiveExternalEvent();
};
**data.cpp"
#include "data.h"
void Data::Init()
{
// The value actually come from file, but this is enough for my example
param1 = 5;
}
int IncreaseParam1()
{
param1 += 5;
return param1;
}
// This is called from (for example) a communication class that has a
// pointer to the same object that the interface class object has
void ReceiveExternalEvent()
{
IncreaseParam1();
// NOW HERE IT WOULD HAVE TO CALL A METHOD TO UPDATE THE INTERFACE
// WITH THE NEW PARAM1 VALUE!
}
I hope I made myself clear enough.
Can someone please give me ideas on how to deal with this situation?
Thanks a lot in advance!
Both Data and Interface are singletons. You expect to only have one instance of each class in existence. So:
Class Data {
public:
static Data *instance;
Data()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Class Interface {
public:
static Interface *instance;
Interface()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Now, ReceiveExternalEvent() will simply invoke Data::instance->method() and/or Interface::instance->method(), and so on...
This is a classical singleton design pattern.
Also, you might find some additional Google food of likely interest to you: "model view controller" and "mvc".

Understanding Abstraction in C++

Coming from Java to C++ I'm attempting to understand abstraction through object orientation.
To put this into a practical example, I am developing a small game using the SFML library for graphics. However this question does not relate to that, simply think of it as background info. Anyway, the way the game works is to process through a number of different states. In this case 2:
The Menu State: The menu of the game is drawn and the game will begin here.
The Game State: This state controls the game, will update entities and draw them.
In order to do this I have created the following classes:
GameStateManager.h
#ifndef GAMESTATEMANAGER_H
#define GAMESTATEMANAGER_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "GameState.h"
class GameStateManager
{
public:
// Constructor
GameStateManager();
// State variables
static const int NUMGAMESTATES = 2;
static const int MENUSTATE = 0;
static const int GAMESTATE = 1;
// Public Functions
void set_state(int state);
void update();
void draw(sf::RenderWindow &win);
void input(sf::Event event);
private:
// Array of gamestates
GameState game_states[];
// The current state
int current_state;
// Private functions
void load_state(int state);
void unload_state(int state);
};
#endif
GameState.h
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <iostream>
#include <SFML/Graphics.hpp>
#include "GameStateManager.h"
class GameState
{
protected:
GameStateManager gsm;
public:
virtual void init() = 0;
virtual void update() = 0;
virtual void draw(sf::RenderWindow &win) = 0;
virtual void input(sf::Event event) = 0;
};
#endif
Now you may have noticed the Array of GameStates in Game State Manager? This provides an error to which I do not understand: zero-sized array. Does this mean initialization needs to be made within the header file? Further to this point the compiler mentions an Array of Abstract class isn't allowed?
The second issue is that the field gsm in the abstract GameState class does not recognize and brings up yet another error: Missing type specifier.
Now to complicate things further I have the following class: MenuState. This class is meant to extend GameState.
MenuState.h
#ifndef MENUSTATE_H
#define MENUSTATE_H
#include "GameState.h"
class MenuState: public GameState
{
public:
MenuState(GameStateManager gsm);
void init();
void update();
void draw(sf::RenderWindow &win);
void input(sf::Event event);
private:
sf::Texture title_texture;
sf::Sprite title_sprite;
};
#endif
As mentioned this class will control the menu of the game.
Implementing GameStateManager is done as follows:
GameStateManager.cpp
/*
* GameState Manager will take care of the various states of the game.
* In particular there will be two states: Menu or Ingame. GameStateManager
* will load and unload each state as needed.
*
* Author: Ben Euden
* Date: 2/5/2014
*/
#include "GameStateManager.h"
// Class Constructor
GameStateManager::GameStateManager()
{
game_states = game_states[NUMGAMESTATES];
current_state = MENUSTATE;
load_state(current_state);
}
/*
* Load the current game by creating and initialising the state
* then storing it in the game_states array.
* #Param state The state we wish to load.
*/
void GameStateManager::load_state(int state)
{
if(state == MENUSTATE)
game_states[state] = MenuState(this);
//if(state == GAMESTATE)
//game_states[state] = MainGameState(this); // Not implemented yet.
}
/*
* Unload the state we loaded with load_state
*/
void GameStateManager::unload_state(int state)
{
game_states[state] = NULL;
}
void GameStateManager::set_state(int state)
{
unload_state(state);
current_state = state;
load_state(state);
}
void GameStateManager::update()
{
try{
game_states[current_state].update();
}
catch(int e)
{
std::cout << "Exception occured during update of game state" << e << std::endl;
}
}
void GameStateManager::draw(sf::RenderWindow &win)
{
try{
game_states[current_state].draw(&win);
}
catch(int e)
{
std::cout << "Exception occured when trying to draw gamestate: " << current_state << "Exception number: " << e << std::endl;
}
}
void GameStateManager::input(sf::Event event)
{
game_states[current_state].input(event);
}
And MenuState as follows:
/*
* This class extends the Game State header and will deal with the menu of the game
* this includes drawing the correct text to the screen, moving the selector and
* either exiting, bringing up about or starting the game.
*
* Author: Ben Euden
* Date: 2/5/2014
*/
#include "MenuState.h"
MenuState::MenuState(GameStateManager gsm)
{
gsm = gsm;
init();
}
void MenuState::init()
{
title_texture = sf::Texture();
title_texture.loadFromFile("sprites/Title.png");
title_sprite = sf::Sprite();
title_sprite.setTexture(title_texture);
title_sprite.setPosition(512, 200);
}
void MenuState::update(){}
void MenuState::draw(sf::RenderWindow &win)
{
win.draw(title_sprite);
}
void MenuState::input(sf::Event event)
{
}
Please ignore inplemented methods and positionings. At this point I began to attempt to compile the project (I'm using Visual Studio) when the errors appeared.
Now in understand that the MainGameState hasn't been implemented yet but even with MenuState I'm sure I'm missing something vital here as I am still learning C++. With this in mind also please excuse any breakage of conventions etc again I am learning so feel free to correct me, it is better I learn the right way now rather than develop bad habits.
In Summary I'd like to understand why I am receiving the following errors:
protected:
GameStateManager gsm;
This produces the error: missing ';' before gsm.
GameState game_states[];
Produces the errors of: zero-size array, array of abstract class not allowed.
I believe if I fix these the rest will sort themselves out.
Thank you for your patience, time and assistance with this.
Euden
To be short: you don't know any basics of C++, and as a beginner, you should really aproach it as a totally different language than Java or C, so you should stop your project right now and find a good book for C++ beginners. Don't try to mix your Java knowledge and just fill the gaps to reach C++ knowledge, it will not work because even if the syntaxe is close, they are widely different beasts.
I always recommend learning C++ as a new and different language, whatever your background. Right now you are doing big errors that shows you're on the wrong path to learn C++. You should get back to basic tutorials (I'm not trying to be harsh, you really need to learn the basics before even managing to compile this code).
You use of arrays and members like if they were references shows your lack of understanding of "value semantic" and several other basic concepts which are must-known of C++ usage.
For example, if I have
class A
{
int k = 42; // C++11
};
Here a A object will contain a k object. What I mean is that k is not a pointer to an int, it's the actual value, within memory allocated into the A object.
So if I have
A my_object; // object on the stack
Then my_object is an object taking the size of an int. So if I do:
class B
{
int u;
A a;
};
Then an instance of B will actually be the size of a A object, plus the size of an int. B objects will contain all these data in a single block of memory.
So when you do:
class GameState
{
protected:
GameStateManager gsm;
What you actually do here is that you build a full GameStateManager into any GameState object. Yes, gsm is not a reference, it's the full object.
What you should do here is either use a c++ reference (if the game manager should never change) or use a pointer (or a smart poitner if there is ownership involved).
I see a lot of other problems, like your array member into GameStateManager have absolutely not the same meaning than in Java. Basically, you're note coding in C++ here. (and you should use either std::vector or std::array but your GameState are dynamic so it would vector or array of pointers - or even map or another container).
As there is too much to point, I should get to the core point:
Whatever the language that you have learnt before, even C or Java which are related, never ever assume you know anything of C++ yet, you absolutely don't. You need to approach it as a beginner. Learn it as a very new language.
And make sure you read actually good material as the list provided there. It's extremely easy to learn bad practice online about C++, unfortunately (but it gets better).
Also, you might want to read this: https://softwareengineering.stackexchange.com/questions/76675/how-can-a-java-programmer-make-the-most-of-a-new-project-in-c-or-c/76695#76695
By the way, a related recommendation: read "SFML Game Development" book for example of simpler and safer (and C++-idiomatic) ways to do what you are trying to achieve here.
Another side recommendation would be to avoid using "manager" in your type names, it only makes things hard to understand and design.
The "zero-size array" error is caused by GameState game_states[];.
In C++ you have to specify the array size at declaration time, either by specifically writing the size or direct initializing it.
Example:
GameState game_states[ ]; // Error, compiler can't know how much memory to reserve for this.
GameState game_states[4]; // OK, explicit size given, compiler will reserve enough memory for 4 `GameState` objects.
GameState game_states[ ] = { GameState( ), GameState( ) }; // OK, direct initialization, compiler will reserve enough memory for 2 `GameState` object.
In your case it should be:
GameState game_states[ NUMGAMESTATES ];
And you should drop the following line from GameStateManager constructor:
game_states = game_states[NUMGAMESTATES]; // Meaningless in C++.
"Array of Abstract class isn't allowed" arises from this declaration also, the problem is C++ differs from Java here. In C++ this declares a variable which is a GameState instance, which is not allowed because GameState has pure virtual methods and as so can't be instantiated ( Just as Java abstract classes can't be newed ). To achieve this polymorphic behavior in C++ you have to use pointers or references, which is what Java uses implicit for you.
Fixing this should give you:
GameState * game_states[ NUMGAMESTATES ];
"missing ';' before gsm" is happening just because the compiler couldn't compile GameStateManager, fixing the bugs I mentioned should solve this.
Few tips:
Think of variables in C++ as ints from Java, even for types you've declared yourself. Which means they are instantiated just by declaring then ( no new needed ) and they are copied when assigned to another variable. ( no reference semantics by default as Java )
Look for good C++ books/tutorials as you don't seem to understand some very important basic concepts from C++.

Inheritance in Arduino Code

I'm writing some Arduino code and attempting to use inheritance in some classes. I have a class "Actor" (my base class) and a class "Marble" (which inherits from Actor). Here are the header files:
Actor.h:
#ifndef Actor_h
#define Actor_h
#include "Arduino.h"
class Actor
{
public:
Actor();
void speak();
private:
};
#endif
Marble.h:
#ifndef Marble_h
#define Marble_h
#include "Arduino.h"
#include "Actor.h"
class Marble : public Actor {
public:
Marble();
virtual void speak();
private:
};
#endif
Actor.cpp:
#include "Arduino.h"
#include "Actor.h"
Actor::Actor()
{
}
void Actor::speak() {
Serial.println("Actor");
}
Marble.cpp:
#include "Arduino.h"
#include "Marble.h"
void Marble::speak() {
Serial.println("Marble");
}
And finally, in the loop function I do:
void loop() {
Marble marble;
Actor children[2];
children[0] = marble;
children[0].speak();
Which results in "Actor" being printed.
I discovered this nice link which seems similar to my issue, but the resolution does not seem to work for me:
http://arduino.cc/forum/index.php?topic=41884.0
So. It seems like when I create my array of "Actors" and try and stick Marble in there it gets cast to an Actor, or something like that. Problem is, I'll have a few different characters that will all inherit from "Actor" and I'd like an array of them to iterate over and call overridden methods on them.
So, perhaps the problem is how I'm approaching this problem, or maybe there's some syntax errors? I don't know!
Thanks for your help,
Kevin
You need to declare speak as virtual in the Actor class, not just in the Marble class; without that, Actor::speak is a non-virtual function, so you will always be called in preference to the virtual Marble::speak.
For what it's worth, this has nothing to do with the Arduino: it's just a straight C++ issue.
Your problem is that children is an array of type Actor. The line children[0] = marble is taking a Marble object, converting it to an Actor object and copying the results to children[0]. Since the call to children[0].speak() is on an Actor, you get the Actor version.
In order for this to work the way you want, you need to copy a pointer or reference to the object rather than the object itself. That is, you want something like `Actor* children[2]':
Marble marble;
Actor* children[2];
children[0] = &marble;
children[0]->speak();
Of course if children has scope outside of loop, this will fail utterly and you'll need to use new to create your marbles.
Better yet, assuming Arduino has the STL, you should use vector and shared_ptr or something similar.
[Update] As Philip notes, this will also require that the speak method in Actor be declared virtual.

working with C++ fuzzylite lib and ObjC in iOS (fuzzy logic)

I've wandered into the deep end of the pool here. I've made some good progress but now am just thrashing around. I'm trying to use this fuzzy logic lib in iOS: http://code.google.com/p/fuzzy-lite/
I've got it to compile - what I did was to add both the .cpp & the .h files to my project and changed the suffix on my main viewController to ".mm". I am able to run the fuzzyLite test.h file from within viewDidload (show below). It runs and the test data is displayed.
What I need to do is create a persistent instance of fuzzyLite so I can use it in my app (e.g. be able to address it and then clean up when the app unloads).
I've searched around but haven't understood the discussions/examples of including C++ code in an ObjC project. Can someone show me a way I can move forward with this - wrapping the fuzzyLite code so I can call functions and get results back? Thanks!
EDIT: I've made progress on this using the method detailed here:
http://robnapier.net/blog/wrapping-c-take-2-1-486
One thing I am unclear on is memory cleanup. The dealloc function cleans up the instance of the wrapped CPP instance - but what about memory alloc'ed within the CCP instance? Seems like I need call a method to release that prior to deleting the instance.
ex: the wrapped class has some instance vars of subclasses- is my cleanup function enough to manage the memory properly?
void Bingo::cleanup(){
delete engine;
engine = NULL;
delete health;
health = NULL;
delete energy;
energy = NULL;
}
-header for the wrapped CPP class
#include "fuzzylite/FuzzyLite.h"
namespace fl {
class Bingo {
public:
FuzzyEngine* engine;
OutputLVar* health;
InputLVar* energy;
Bingo();
void Fuzz();
void setInput(float input);
};
}
from the ObjC wrapper:
- (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("--");
}
}
It's basically not possible to answer your question given the information provided. Your question is about the cleanup method of the Bingo class, but instances of Bingo (either on the stack or the heap) appear nowhere in your code excerpts. Likewise, you state that you are cleaning up a "wrapped CPP instance" but it's referenced nowhere else. It does appear that you have leaks in your Test::SimplMamdani method -- you new a bunch of objects there that don't [at least in the revealed code] have any corresponding deletes. Similarly, in your FuzzyLiteIOSViewController::viewDidLoad method you create a Test instance on the heap without a corresponding delete. I'm assuming that there's no autoptr stuff going on under the hood in your C++ code.
UPDATED to provide additional information:
Based upon your comment, you need to review the basic language structure of C++. The basic rule is that you'll need to delete anything that you new. Clean up for the Bingo class should be performed in the destructor (a C++ construct to Objective-C's dealloc). Your Bingo class should look something more like:
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;
}
}
When you delete a Bingo instance, the destructor will be called and Bingo's member variables will be disposed.
Arguably your member variables (engine, health, and energy) should be private in scope and exposed via public-scoped getters and setters.
Grab a copy of Bjarne Stroustrup's C++ reference and give it a quick perusal, or use an online get-up-and-going guide like this one.