Different values of class member in constructor and out of it - c++

That would be one of those super-simple-questions but I really can't remind myself why is that going on. So: I have a simple constructor in which I initialize some variables, int in this example, and I also have a method that helps me to print this int out. But what is wrong is in constructor I have right value of my int, but outside I get some random stuff. Why is that happening and how to prevent it?
Here's player.cpp:
#include "player.h"
#include <iostream>
player::player()
{
int position = 1;
}
void player::get_pos()
{
std::cout << "You position is: " << this->position << std::endl;
}
and player.h
#ifndef PLAYER_H
#define PLAYER_H
class player
{
int position;
public:
player();
void get_pos();
};
#endif // PLAYER_H
I have also tried it without this->position but it is not working anyway. This seems accurate to me, because I want to know the position of THIS object.

You constructor:
player::player()
{
int position = 1;
}
Is declaring a local variable called position and setting that rather than setting the class member as expected.
try:
player::player()
{
position = 1;
}

Related

Superclass member pointer becomes null when accessed by subclass

I've been recently doing a lot of reading and decided to try and implement a simple State pattern to try and see how things fit together.
However, I've ran into an issue I've never come across before: The Scene's subclass (Start) doesn't seem to inherit the value of a pointer set by the superclass' constructor.
Here's the code
//main.cpp
#include "Game/game.hpp"
#include "Game/Scene/start.hpp"
int main()
{
Game::Game *g = new Game::Game;
Game::Scene::Start *s = new Game::Scene::Start(g);
g->set_scene(s);
g->loop();
delete g;
return 0;
}
//Game/Scene/Scene.hpp
#ifndef GAME_SCENE_H
#define GAME_SCENE_H
namespace Game
{
class Game;
namespace Scene
{
class Scene
{
public:
Scene(Game *game);
virtual ~Scene();
virtual void handle_input() = 0;
virtual void update();
protected:
Game *game;
};
}
}
#endif
//Game/Scene/Scene.cpp
#include "scene.hpp"
#include <iostream>
Game::Scene::Scene::Scene(Game *game): game(game)
{
std::cout << "Game::Scene::Scene::Scene() > game: " << this->game << std::endl;
}
Game::Scene::Scene::~Scene() {}
void Game::Scene::Scene::update()
{
std::cout << "Game::Scene::Scene::update(): game: " << game << std::endl;
}
//Game/Scene/start.hpp
#ifndef GAME_SCENE_START_H
#define GAME_SCENE_START_H
#include "scene.hpp"
namespace Game
{
namespace Scene
{
class Start:
public Scene
{
public:
Start(Game *game);
void handle_input() override;
void update() override;
protected:
Game *game;
};
}
}
#endif
//Game/Scene/start.cpp
#include "start.hpp"
#include "../game.hpp"
#include <iostream>
Game::Scene::Start::Start(Game *game): Scene(game) {
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
void Game::Scene::Start::handle_input()
{}
void Game::Scene::Start::update()
{
Scene::update();
std::cout << "Game::Scene::Start::update(): game: " << game << std::endl;
game->set_keep_going(false);
}
//Game/game.hpp
#ifndef GAME_H
#define GAME_H
#include "Scene/scene.hpp"
namespace Game
{
class Game
{
public:
Game();
void loop();
void set_keep_going(bool state);
void set_scene(Scene::Scene *scene);
private:
bool keep_going;
Scene::Scene *current_scene;
};
}
#endif
//Game/game.cpp
#include "game.hpp"
#include <iostream>
Game::Game::Game():
keep_going(true),
current_scene(nullptr)
{}
void Game::Game::loop()
{
while(keep_going && current_scene)
{
current_scene->handle_input();
current_scene->update();
}
return;
}
void Game::Game::set_keep_going(bool state)
{
keep_going = state;
}
void Game::Game::set_scene(Scene::Scene *scene)
{
if(scene)
{
if(current_scene)
{
delete current_scene;
}
current_scene = scene;
}
}
And here is the output it generates:
Game::Scene::Scene::Scene() > game: 00000210FA38B330
Game::Scene::Start::Start() > game: 0000000000000000
Game::Scene::Scene::update(): game: 00000210FA38B330
Game::Scene::Start::update(): game: 0000000000000000
Segmentation fault
If I remove the 'this->' part that I used in the subclass constructor for debugging the output becomes this
Game::Scene::Scene::Scene() > game: 000001D247B5B370
Game::Scene::Start::Start() > game: 000001D247B5B370
Game::Scene::Scene::update(): game: 000001D247B5B370
Game::Scene::Start::update(): game: 0000000000000000
Segmentation fault
Which just makes it even weirder to me that it suddenly decided to reset itself.
It's without a doubt an incredibly simple thing that I'm overlooking, or some pointer shennanigans I've never run into before, but I'm stumped on what can possibly be going on here.
Any help or feedback om my code would be appriciated.
You have two members variables Scene::game and Start::game. You never set Start::game. By default, game resolves to Scene::game and the base class's variable is shadowed. Turn on compiler warnings, maybe the compiler will warn about it, not sure in this particular case.
Fix:
Game::Scene::Start::Start(Game *game): Scene(game), game(game)
{
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
Or just delete Start::game and use the member from Scene. This probably what you have meant in the first place hence the protected qualifier.
If you want feedback - do not use new, use std::unique_ptr instead. Even better, do not use ptrs at all this is not Java.

Trying to access variables from another class

Im having an issue getting my variable from my original class to print in another class method
Quick example of my issue:
say the variable was declared here in the test.h file:
class player{
private:
int x = 10;
void setX(); //method for setting X from user input
int getX(); //Method for retrieving variable
}
Then in another class method where i want to print X
class inTheWoods{
public:
printInfo();
}
test.cpp file:
void player::setX(){
cout << "Set X to a number:" << endl;
cin >> x
}
int player::getX(){
return x;
}
int inTheWoods::printInfo(){
player playerObj; //Player object to access methods in player class
cout << playerObj.getX();
}
main.cpp:
int main(){
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Whenever I run my program that resembles this problem the int does not display correctly and throws me a strange negative number. I hope this isnt too much code and that I documented everything correctly
If you want the classes to be in a separate files, it should still work:
Main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Player.h
#pragma once
#include <iostream>
class Player
{
int x = 10;
void setX();
public:
int getX();
};
Player.cpp
#include "Player.h"
void Player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> x;
}
int Player::getX()
{
return x;
}
inTheWoods.h
//#pragma once
#include "Player.h"
#include <iostream>
class inTheWoods
{
public:
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
void inTheWoods::printInfo()
{
Player playerObj; //Player object to access methods in player class
std::cout << playerObj.getX();
}
#pragma once is a preprocessor that prevents multiple includes, in case you didn't know. You can choose to skip it (Visual Studio auto-generated the file with the line).
In summary, these are the changes I needed to make from your implementation:
Move declaration of getX() from private to public.
Add semicolons to the end of every class.
Add a return type to printInfo(). If you don't want a function to return anything, the return type is void. Unless you care declaring a constructor, which doesn't seem to be the case here.
Here is the working one. It's always a good practice to give a constructor, in order to create an instance with some default values. the following code will work hopefully according to your requirements:
main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
player.h
#pragma once
class player
{
private:
int m_x;
public:
player();
player(const int& x);
void setX(); //method for setting X from user input
const int& getX()const; //Method for retrieving variable
};
player.cpp
#include "player.h"
#include <iostream>
player::player() // defualt constructor
:m_x(0) {}
player::player(const int& x)
:m_x(x) {} // parameterised
void player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> m_x;
}
const int& player::getX()const
{
return m_x;
}
inTheWoods.h
#pragma once
class inTheWoods
{
public:
inTheWoods();
~inTheWoods();
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
#include "player.h"
#include <iostream>
inTheWoods::inTheWoods() {}
inTheWoods::~inTheWoods() {}
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
player playerObj2(10); // will beinitialized with 10
std::cout << playerObj.getX() <<std::endl;
std::cout << playerObj2.getX() <<std::endl;
}
Edit: Well if you wanna allow the user to set values your printInfo() must be as follows:
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
playerObj.setX();
std::cout << playerObj.getX() <<std::endl;
}

C++ SFML Segfault between renderer and object

Before I start, I'm going to apologize ahead of time for any seemingly obvious mistakes I may have made. I'm pretty in over my head at this point and there's probably quite a few errors in here.
Any suggestions on fixing what I have, or better ways of setting up what I want are appreciated.
I have two classes, the Renderer and the FParticle.
What I want is for the FParticle constructor to pass a pointer of itself to the Renderer. The Renderer will store the various FParticle pointers in a vector and then when DrawObjects() is called, it will draw all of the objects using the list of pointers.
This way I don't have to worry about passing each particle into the renderer each step of the game loop, and can instead just draw them from the list of pointers.
The problem is that the program is segfaulting and I can't figure out how to deal with it.
The segfault occurs in renderer.cpp
The files are here:
renderer.h
#pragma once
#ifndef RENDERER_H
#define RENDERER_H
#include <SFML/Graphics.hpp>
#include <vector>
class FParticle;
class Renderer {
private:
std::vector<const FParticle*> object_buffer_;
sf::RectangleShape rectangle_;
public:
Renderer();
void addObject(const FParticle &object);
void drawObjects(sf::RenderWindow &window);
};
#endif // RENDERER_H
renderer.cpp
#include "renderer.h"
#include "fparticle.h"
#include <iostream>
Renderer::Renderer() {}
void Renderer::addObject(const FParticle &object)
{
object_buffer_.push_back(&object);
}
void Renderer::drawObjects(sf::RenderWindow &window)
{
for (int i = object_buffer_.size(); i > 0; i--)
{
rectangle_.setSize(object_buffer_[i]->get_size()); // <------- SEGFAULT HERE
rectangle_.setPosition(object_buffer_[i]->get_position());
rectangle_.setFillColor(sf::Color::White);
std::cout << object_buffer_[i]->get_size().x << std::endl;
window.draw(rectangle_);
}
}
fparticle.h
#pragma once
#ifndef FPARTICLE_H
#define FPARTICLE_H
#include <SFML/Graphics.hpp>
class Renderer;
class FParticle
{
protected:
sf::Vector2f size_;
sf::Vector2f position_;
sf::Vector2f velocity_;
sf::Vector2f acceleration_;
float inverse_mass_;
float damping_;
public:
FParticle(Renderer &picasso);
sf::Vector2f get_size() const;
sf::Vector2f get_position() const;
void set_mass();
void set_inverse_mass();
};
#endif // FPARTICLE_H
fparticle.cpp
#include "fparticle.h"
#include "renderer.h"
#include <iostream>
FParticle::FParticle(Renderer &picasso)
{
size_.x = 5.f;
size_.y = 5.f;
position_.x = 10.f;
position_.y = 10.f;
picasso.addObject(*this);
}
sf::Vector2f FParticle::get_size() const
{
return size_;
}
sf::Vector2f FParticle::get_position() const
{
return position_;
}
pseudo main.cpp
int main()
{
Renderer picasso;
FParticle p1(picasso);
while(gamestate != Exiting)
{
window.clear(Black);
picasso.drawObjects(window_);
window.display();
}
return 0
}
Like I said, I'm relatively in over my head and am still in the early stages of learning. Any suggestions or advice on anything are appreciated.
Your vector is only indexible from 0... size-1. You're starting at size, thus out of range, thus invoking undefined behavior, thus (because you were actually fortunate) your crash.
Use an iterator for your collection. If you want this in reverse, use a reverse-iterator.
for (auto it = object_buffer.rbegin(); it != object_buffer.rend(); ++it)
{
rectangle_.setSize((*it)->get_size());
rectangle_.setPosition((*it)->get_position());
rectangle_.setFillColor(sf::Color::White);
std::cout << (*it)->get_size().x << std::endl;
window.draw(rectangle_);
}
or something to that effect.
Note: When in doubt, replace vector/deque operator[i] usage with obj.at(i) accessors instead. The latter is range-checked and will bark at you via assertion the moment you pass an invalid-ranged index.
Best of luck.

Access variable from another class (in C++)

This may be a really easy question but... here it goes. (Thanks in advance!)
I am simplifying the code so it is understandable. I want to use a variable calculated inside another class without running everything again.
source.ccp
#include <iostream>
#include "begin.h"
#include "calculation.h"
using namespace std;
int main()
{
beginclass BEGINOBJECT;
BEGINOBJECT.collectdata();
cout << "class " << BEGINOBJECT.test;
calculationclass SHOWRESULT;
SHOWRESULT.multiply();
system("pause");
exit(1);
}
begin.h
#include <iostream>
using namespace std;
#ifndef BEGIN_H
#define BEGIN_H
class beginclass
{
public:
void collectdata();
int test;
};
#endif
begin.cpp
#include <iostream>
#include "begin.h"
void beginclass::collectdata()
{
test = 6;
}
calculation.h
#include <iostream>
#include "begin.h"
#ifndef CALCULATION_H
#define CALCULATION_H
class calculationclass
{
public:
void multiply();
};
#endif
calculation.cpp
#include <iostream>
#include "begin.h"
#include "calculation.h"
void calculationclass::multiply()
{
beginclass BEGINOBJECT;
// BEGINOBJECT.collectdata(); // If I uncomment this it works...
int abc = BEGINOBJECT.test * 2;
cout << "\n" << abc << endl;
}
Simply define member function multiply as
void calculationclass::multiply( const beginclass &BEGINOBJECT ) const
{
int abc = BEGINOBJECT.test * 2;
cout << "\n" << abc << endl;
}
And call it as
int main()
{
beginclass BEGINOBJECT;
BEGINOBJECT.collectdata();
cout << "class " << BEGINOBJECT.test;
calculationclass SHOWRESULT;
SHOWRESULT.multiply( BEGINOBJECT );
system("pause");
exit(1);
}
In your code beginclass has no explicit constructor, hence the implicitly defined default constructor will be used, which default constructs all members. Hence, after construction beginclass::test is either 0 or uninitiliased.
What you appear to be wanting is to avoid to call beginclass::collectdata() more than once. For this you would want to set a flag that remembers if beginclass::collectdata() has been called. The member function which returns the data then first checks this flags and, if the flag was not set, calls beginclass::collectdata() first. See also the answer by CashCow.
It looks like you are looking for some kind of lazy evaluation / caching technique whereby a value is calculated the first time it is requested then stored to return it subsequently without having to reevaluate.
In a multi-threaded environment the way to achieve this (using the new standard thread library) is by using std::call_once
If you are in a single-threaded environment, and you just want to get a value out of a class, use a getter for that value. If it isn't calculated in a "lazy" fashion, i.e. the class calculates it instantly, you can put that logic in the class's constructor.
For a "calc_once" example:
class calculation_class
{
std::once_flag flag;
double value;
void do_multiply();
double multiply();
public:
double multiply()
{
std::call_once( flag, do_multiply, this );
return value;
}
};
If you want multiply to be const, you'll need to make do_multiply also const and value and flag mutable.

Polymorphic classes not behaving as expected

I'm programming some arduino code, but things aren't quite going to plan.
What am I doing wrong here? I've read around and tried to educate myself about virtual functions, but perhaps I've missed something. Go to QUESTIONSHERE for the actual questions to which I need answers, but first, some explanation:
The Classes RGBPixel and colorGenerator both derive from colorSource, which provides public functions getR(), getG() and getB() so that another pixel or color modifier can take a copy of their current colour.
Classes derived from colorGenerator implement the colour generation code so that they can generate their own colour, while RGBPixels have a colorSource *parent member, so they can obtain a color value from a colorGenerator or another RGBPixel.
In my example, I have one colorGenerator subclass (CG_EmeraldWaters, which should create me a variety of greens and blues), and then a number of RGBPixels in an array. RGBPixels[0] should take its value from an instance of GC_EmeraldWaters, while RGBPixels[1] takes its value from RGBPixels[0], [2] from [1], [n] from [n-1]. The pixels seem to be pulling a color from their parent just fine, but either the first pixel in the chain isn't querying the colorGenerator properly, or the colorGenerator isn't updating properly.
To update the colorGenerator, a colorController class oversees the whole process:
colorController.h:
#ifndef _COLORCONTROLLER_H
#define _COLORCONTROLLER_H
#include <list>
#include "colorGenerator.h"
#include "RGBPixel.h"
#include "globals.h"
#include "Arduino.h"
unsigned long millis();
typedef std::list<colorGenerator> generatorList;
class colorController
{
public:
virtual bool refresh();
protected:
generatorList generators;
};
#endif //_COLORCONTROLLER_H
As you can see, the controller has a list of colorGenerators and method to refresh them all (called from loop()), which unless overridden in the child class, does this:
bool colorController::refresh()
{
for (generatorList::iterator it = generators.begin(); it != generators.end(); ++it)
it->refresh();
bool dirty = false;
for (int i = NUM_OF_LEDS-1; i >= 0; --i)
dirty |= RGBPixels[i].refresh();
return dirty;
}
The CC_Cascade class (derived from colorController) sets things up like this:
CC_Cascade.h
#ifndef _CC_CASCADE_H
#define _CC_CASCADE_H
#include "colorController.h"
class CC_Cascade : public colorController
{
public:
CC_Cascade();
~CC_Cascade();
};
#endif //_CC_CASCADE_H
CC_Cascade.cpp
#include "CC_Cascade.h"
#include "CG_EmeraldWaters.h"
CC_Cascade::CC_Cascade()
{
colorGenerator * freshBubblingSpring = new CG_EmeraldWaters();
generators.push_back(*freshBubblingSpring);
RGBPixels[0].setParent(freshBubblingSpring);
RGBPixels[0].setDelay(40);
for (int i = 1; i < NUM_OF_LEDS; ++i)
{
RGBPixels[i].setParent(&RGBPixels[i-1]);
RGBPixels[i].setDelay(500-(9*i)); //FIXME: magic number only works for 50ish pixels
}
}
CC_Cascade::~CC_Cascade()
{
//TODO: delete generators
}
So far so clear?
Let me draw your attention to the colorController::refresh() function. What should happen is that every time it's called, there's one colorGenerator in the generators list (because the CC_Cascade constructor put it there), which is a CG_EmeraldWaters. When refresh() is called on this (through the iterator), it calls colorGenerator::refresh(), which in turn calls updateColor(). In the case of CG_EmeraldWaters, this is overriden, so CG_EmeraldWaters::updateColor SHOULD be called, giving a turquoise colour. Using some serial write statements to debug, I can see that IN FACT colorGenerator::updateColor() is called, so in that case I'd expect an orangey colour, BUT neither of these is affecting the colour of the pixels, which are all staying a purple colour as set in the CG_EmeraldWaters contructor.
Doing a little messing about, I added the following line to colorGenerator::updateColor(): RGBPixels[0].setColor(255,127,0);
Rather than the orange colour I was hoping for, the first pixel alternated quickly between purple and orange, suggesting (IMHO) that my new line of code was doing its job, but then the pixel was pulling its original purple colour again from the colorGenerator, and that somehow colorGenerator::updateColor() doesn't change the colour of the colorGenerator (given that I don't get a compile error, what IS it changing?).
So my qustions are: (QUESTIONSHERE)
1) How can I change the value of colorSource::currentR(/G/B) from within colorGenerator::updateColor(), given that currentR(/G/B) is declared as protected in colorSource and that colorGenerator is directly derived from colorSource?
2) Given an instance of CG_EmeraldWaters, how can I call CG_EmeraldWaters::updateColor() via colorGenerator::refresh(), which CG_EmeraldWaters inherits, given that updateColor() is declared as virtual in colorGenerator and overriden in CG_EmeraldWaters?
Below is the code of colorGenerator and CG_EmeraldWaters:
colorSource.h:
#ifndef _COLORSOURCE_H
#define _COLORSOURCE_H
#include "Arduino.h"
#ifdef DEBUG
#include "colorGenerator.h" //FIXME: delete Me
#endif
//#define byte unsigned char
typedef byte colorStorage_t;
class colorSource
{
public:
colorSource();
colorSource(colorStorage_t initialR, colorStorage_t initialG, colorStorage_t initialB);
void setColor(colorStorage_t newR, colorStorage_t newG, colorStorage_t newB);
//TODO: better implementation than this
colorStorage_t getR();
colorStorage_t getG();
colorStorage_t getB();
bool hasChanged();
protected:
colorStorage_t currentR;
colorStorage_t currentG;
colorStorage_t currentB;
bool dirty;
#ifdef DEBUG
friend colorGenerator; //FIXME: delete Me
#endif
};
#endif //_COLORSOURCE_H
colorSource.cpp:
#include "colorSource.h"
colorSource::colorSource()
{
//nothing here
}
colorSource::colorSource(colorStorage_t initialR, colorStorage_t initialG, colorStorage_t initialB)
:
currentR(initialR),
currentG(initialG),
currentB(initialB)
{
//intialised in the list
Serial.println("Constructed Color Source with initial color");
}
void colorSource::setColor(colorStorage_t newR, colorStorage_t newG, colorStorage_t newB)
{
currentR = newR;
currentG = newG;
currentB = newB;
}
colorStorage_t colorSource::getR()
{
return currentR;
}
colorStorage_t colorSource::getG()
{
return currentG;
}
colorStorage_t colorSource::getB()
{
return currentB;
}
bool colorSource::hasChanged()
{
return !dirty;
}
colorGenerator.h:
#ifndef _COLORGENERATOR_H
#define _COLORGENERATOR_H
#include "colorSource.h"
#ifdef DEBUG
#include "RGBPixel.h" //delete me, used for debugging!
#include "globals.h" //and me!
#endif
extern "C" unsigned long millis();
class colorGenerator : public colorSource
{
public:
colorGenerator(colorStorage_t initialR, colorStorage_t initialG, colorStorage_t initialB);
bool refresh();
protected:
virtual void updateColor();
unsigned long nextColorUpdate = 0;
unsigned short delay = 40;
};
#endif //_COLORGENERATOR_H
colorGenerator.cpp:
#include "Arduino.h"
#include "colorGenerator.h"
colorGenerator::colorGenerator(colorStorage_t initialR, colorStorage_t initialG, colorStorage_t initialB)
:
colorSource(initialR,initialG,initialB)
{
//intialised in the list
//Serial.println("Constructed Color Generator");
}
bool colorGenerator::refresh()
{
#ifdef DEBUG
Serial.print("colorGenerator::refresh()");
#endif
if (millis() < nextColorUpdate)
return false;
nextColorUpdate = millis() + (unsigned long) delay;
this->updateColor();
return true;
}
void colorGenerator::updateColor() //this function gets called (even if it has been overridden in a child class), but the code in it doesn't have the desired effect
{
#ifdef DEBUG
//Serial.print("colorGenerator::updateColor()");
//RGBPixels[0].setColor(255,127,0);
#endif
currentR = random(127,255);
currentG = random(0,127);
currentB = 0;
}
CG_EmeraldWaters.h:
#ifndef _CG_EMERALDWATERS_H
#define _CG_EMERALDWATERS_H
#include "colorGenerator.h"
#include "globals.h"
#include "RGBPixel.h"
class CG_EmeraldWaters : public colorGenerator
{
public:
CG_EmeraldWaters();
protected:
void updateColor();
};
#endif //_CG_EMERALDWATERS_H
CG_EmeraldWaters.cpp:
#include "Arduino.h"
#include "CG_EmeraldWaters.h"
CG_EmeraldWaters::CG_EmeraldWaters()
:
colorGenerator(255,0,255) //this color seems to stick! Changes made by updateColor() aren't propogated to the pixels.
{
//initialised in list
//Serial.println("Constructed Emerald Waters");
}
long random(long,long);
void CG_EmeraldWaters::updateColor() //this never seems to be called!
{
currentR = 0;
currentG = random(0,255);
currentB = random(0,255);
}
And finally, the main sketch file:
#include "FastSPI_LED2.h"
#include <StandardCplusplus.h>
#include "colorController.h"
#include "RGBPixel.h"
#include "globals.h"
#include "CC_Cascade.h"
colorController * currentColorController;
RGBPixel RGBPixels[NUM_OF_LEDS];
struct CRGB ledString[NUM_OF_LEDS];
void setup()
{
#ifdef DEBUG
//debugging:
Serial.begin(9600);
Serial.println("In Setup");
#endif
// sanity check delay - allows reprogramming if accidently blowing power w/leds
//delay(2000);
LEDS.setBrightness(8);
LEDS.addLeds<WS2801>(ledString, NUM_OF_LEDS);
currentColorController = new CC_Cascade();
}
void writeValuesToString()
{
for (int i = 0; i < NUM_OF_LEDS; ++i)
ledString[i] = CRGB(RGBPixels[i].getR(),RGBPixels[i].getG(),RGBPixels[i].getB());
LEDS.show();
}
void loop()
{
static bool dirty = false; //indicates whether pixel values have changed since last hardware write
//unsigned long lastHardwareWrite = 0; //time of last hardware write - only do this once per milisecond to avoid flicker (this method doesn't work, still flickers)
dirty |= currentColorController->refresh();
if (dirty)
{
dirty = false;
writeValuesToString();
delay(1); //to prevent flicker
}
}
Your problem is due to the so-called object slicing. Here is what is going on: when you declare a list of type generatorList
typedef std::list<colorGenerator> generatorList;
its members are restricted to what is in colorGenerator. Nothing from the derived class matters, so when you push
colorGenerator * freshBubblingSpring = new CG_EmeraldWaters();
generators.push_back(*freshBubblingSpring);
the CG_EmeraldWaters part that is not also in colorGenerator gets "sliced off"; you end up with a version of colorGenerator.
The reason for this is described in the wikipedia article linked above. To fix this problem, change the list to contain pointers, preferably smart pointers, pointing to colorGenerator instances. Then the slicing problem will no longer be relevant:
typedef std::list<unique_ptr<colorGenerator> > generatorList;
...
unique_ptr<colorGenerator> freshBubblingSpring(new CG_EmeraldWaters());
generators.push_back(freshBubblingSpring);
You should be able to call the base class's private and protected methods from the derived class, unless I'm missing something.
To call an overidden method (e.g. virtual foo() is defined in class Base and overridden in class Derived), you can access the Base method by calling derivedObj.Base::foo() in your code.