member function does not change values

I am currently programming my RGB LEDCube and therefor I create color gradients in seperate classes. Those classes are derived from colorgnt.h. I dervied rainbowgnt.h from colorgnt.h. A colorgnt has a virtual rgb8bit(24bit RGB) function that delivers the wanted values dependant on uint8_t position. But I keep getting the number 0 but it should be 255. Why?
Code:

/*
colorgnt.h
*/
#ifndef colorgnt_H
#define colorgnt_H
#include "LEDCube.h"

typedef struct rgb8bit {
	uint8_t r;
	uint8_t g;
	uint8_t b;
};

class colorgnt {
  public:
  colorgnt() {}
  virtual rgb8bit rgb(uint8_t position) {}
};
#endif
/*
rainbowgnt.h
*/
#ifndef rainbowgnt_H
#define rainbowgnt_H
#include "colorgnt.h"
#include "LEDCube.h"
class colorgnt;  //is this neccessary? 
class rainbowgnt: public colorgnt {
  public:
  rainbowgnt() {}
  
  virtual rgb8bit rgb(uint8_t position) {
	rgb8bit rgb;
	rgb.r = 255;  //just for testing, no rainbow
	rgb.g = 255;
	rgb.b = 255;
	return rgb;
  }
};
#endif
void LEDCube::rendergradient(colorgnt gradient) {
  rgb8bit whatever;   
  whatever = gradient.rgb(5);  //Should set whatever.r/g/b to 255
  Serial.println(whatever.r); //Which it doesnt... Delivers '0'
}


void LEDCube::test() {
	rainbowgnt gnt;  //Intializing instance of rainbowgnt
	rendergradient(gnt);  //passing the instance to the function above
}

can you put all of tis into a ingle compilable version?

where is the source for your LedCube class?

void LEDCube::rendergradient(colorgnt gradient)

The problem is that for polymorphism to work in C++ you need to pass your parameters by reference or as a pointer.
In your case, you are passing colorgnt by value in rendergradient. This causes the actual object passed, rainbowgnt gnt, to be sliced into a colorgnt losing the additional stuff in rainbowgnt.

arduarn:

void LEDCube::rendergradient(colorgnt gradient)

The problem is that for polymorphism to work in C++ you need to pass your parameters by reference or as a pointer.
In your case, you are passing colorgnt by value in rendergradient. This causes the actual object passed, rainbowgnt gnt, to be sliced into a colorgnt losing the additional stuff in rainbowgnt.

Thank you! Solved it

BulldogLowell:
can you put all of tis into a ingle compilable version?

where is the source for your LedCube class?

My issue is solved now but this was what I created:

#include <FastLED.h>
#include <Adafruit_NeoPixel.h>
#define DATA_PIN 7
#include "Arduino.h"
#define NUMLEDS 343

#ifndef colorgnt_H
#define colorgnt_H

typedef struct rgb8bit {
  uint8_t r;
  uint8_t g;
  uint8_t b;
};

// COLORGNT CLASS

class colorgnt {
  public:
  colorgnt() {}
  virtual rgb8bit rgb(uint8_t position) {}
};
#endif

// RAINBOWGNT CLASS

#ifndef rainbowgnt_H
#define rainbowgnt_H
class colorgnt;  //is this neccessary? 
class rainbowgnt: public colorgnt {
  public:
  rainbowgnt() {}
  
  virtual rgb8bit rgb(uint8_t position) {
  rgb8bit rgb;
  rgb.r = 255;
  rgb.g = 255;
  rgb.b = 255;
  return rgb;
  }
};
#endif

#ifndef LEDCube_H
#define LEDCube_H

// LEDCUBE CLASS

class LEDCube
{
  public:
  LEDCube(){
  FastLED.addLeds<WS2811, 7>(leds, 343);
  FastLED.setBrightness(255);
  FastLED.clear();
  };
  void rendergradient(colorgnt *gradient) {
  rgb8bit whatever;
  whatever = gradient->rgb(5);
  Serial.println(whatever.r);
  };
  void LEDCube::test() {
  rainbowgnt *gnt;
  rendergradient(gnt);
};
  Adafruit_NeoPixel simulated = Adafruit_NeoPixel(1, 3, NEO_GRB + NEO_KHZ800);
  static const int  limit = 7;
  static const int  limitsqu = limit * limit;
  static const int  numLeds = limitsqu * limit;
  CRGB leds[numLeds];
};
#endif

Adafruit_NeoPixel simulated = Adafruit_NeoPixel(1, 3, NEO_GRB + NEO_KHZ800);

LEDCube cube;

  static const int  limit = 7;
  static const int  limitsqu = limit * limit;
  static const int  numLeds = limitsqu * limit;

void setup() {
  delay(1000);
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  cube.test();
  /*
    cube.ani1();
    cube.sticks(40, 0, true, 255, 255, 255, 20);
    for (int i = 0; i < 21; i++) {
      cube.setall(255, 255, 255);
      delay(100);
    }
      cube.clearLEDs();
      cube.rainbow(5, 256, 'x');
      cube.rainbow(5, 256, 'y');
      cube.rainbow(5, 2 * 256, 'z');
      for (int i = 0; i < limit; i++) {
        cube.setslice('x', i, 255, 0, 0);
        FastLED.show();
        delay(100);
      }
      for (int i = 0; i < limit; i++) {
        cube.setslice('y', i, 0, 255, 0);
        FastLED.show();
        delay(100);
      }
      for (int i = 0; i < limit; i++) {
        cube.setslice('z', i, 0, 0, 255);
        FastLED.show();
        delay(100);
      }
      cube.sticksi(28, 0, false, 0, 0, 0, 0);
      */
}

Passing by reference would probably have been easier and less error prone for a beginner, but either way will work when done correctly. Note that in the following code:

  void LEDCube::test() {
  rainbowgnt *gnt;
  rendergradient(gnt);
};

you have passed an uninitialised pointer into rendergradient and corrupted some random piece of RAM.
rainbowgnt *gnt; only declares a pointer variable but not the storage that it points to and, since it is a local variable, it will have an undefined value inside. You need to:

  • assign a value by allocating with new
  • or take the address of a local instance, ie. rainbowgnt gnt; rendergradient(&gnt);
  • or maybe pass by reference instead.