Pointer to member Function inside the same Class

Hello i have 2 classes and wanna transfer a pointer of a function from Class1 to Class2 (to save it in Class2 so it can be called from the second Class)

class class1
{
public:
  const float& getValue() const;
  void setCallback
  {
  class2(&this->getValue)
  }
}

class class2
{
public:
  class2(const float& (*pGetValue)(void) const)
  {
    pGetValueFunction = pGetValue
  }
  void GetValue()
  {
    return pGetValueFunction();
  }
private:
  const float& *pGetValueFunction const;
}

something like this, but i cant get it to work, the last const throws always an error and it doesnt matter what i try (Class1::getValue, this->getValue all doesnt work) in Class1 it also throws an error, could someone help me with this?

maybe to make it a bit more clear: class1 has many getvalues and i wanna index them with numbers in class2 so internal function can access them via the index number, i need to do this because i have a project which combines many sensors in an universal way (so they can be easly exchanged etc) thats why i cant index them in class1, i need a seperate class to combine (and index) many sensors

so for example: i have a BME680 class which offers 7 getValues of the different sensors (temp, hum etc) now for each "internal" sensor of the BME680 Sensor i wanna call a object of class 2 which has a index number, the getValue function pointing to the right getValue of class1 and the name

You need to study inheritance and virtual member functions.
A non static member function only exist in the context of an instance, you don’t pass pointers around.

Pointers to instance member functions are odd ducks. You can read about them here: https://isocpp.org/wiki/faq/pointers-to-members

1 Like

Not sure what you are trying to do here. class2 is the name of the class, not an instantiation (object) of it. You could create an instance but then it's lifetime would be limited unless you declare it as static.

hmm i tried to read a little about it but couldnt see a way how it is useful so far beside making it more complex, i think you are refering to making Class2 the base class right?
the problem is i need to keep track of many sensors and one base class for all sensors just seem to make things way more complicated than just index them in a seperate class tho im also a noob and maybe i just dont see the right way todo it :frowning:

I just wanna create an object of class2 and transfer indexnumber/getValuePointer and name to class2 in the constructor

it actually looks like this:

Sensors* Sensor1 = NULL;
void class1::Function
{
  Sensor1 = new Sensors(BME680_1_SensorNumber, &BME680::getTemperature, "BME680 Temperature - Min", "BME680 Temperatur - Max");
}

In that case you would have to pass a pointer or reference to the class2 instance to the class1 constructor. That way the when the constructor for the instance of class1 is called it could pass the address of the class1 function to class2.

You will need to use forward declarations to accomplish this.

//BME680(class1.cpp)
extern Sensors* Sensor[20];

extern BME680 pSensor1;

const float& BME680_1_getTemperature()
{
  return pSensor1.getTemperature();  
}

void BME680::sensorSetup()
{
  Sensor[1] = new Sensors(&BME680_1_getTemperature);
}

//class2
class Sensors
{
  public:
    Sensors(const float& (*pGetValue)(void))
    {
      getValueFunction = pGetValue;
    }

    const float& Sensors::getValue()
    {
       return getValueFunction();
    }

  private:
    const float& (*getValueFunction)(void);
};

i got it to work like this (with the global "wrapper" function) but it doesnt seem like the most elegant way but i think there is little i can do with member function pointers beside that or has someone a better idea?

i really wonder how i can make use of inheritance here in a useful way, but i dont come up with a good (and universal) way to do it, even if i have a base class i would need to write 90% in the child sensor classes and in my opinion it just adds a layer of complexity which i kinda wanna avoid

Take a look at how the Adafruit Unified Sensor Library does things.

I still think using inheritance as done in the Adafruit Unified Sensor Library is the way to go. But, something like the code below will "work" (for some definition of "work") and is significantly less-ugly than what you proposed.

You need an ESP or ARM-based "Arduino" board for this. It won't work on an AVR-based board.

#include "Arduino.h"
#include <functional>

using FunctPtr = std::function<float ()>;

class SensorType_pi {
public:
	float getValue() {
		return 3.14159;
	}
};

class SensorType_e {
public:
	float getValue() {
		return 2.71827;
	}
};

class GenericSensor {
public:
	GenericSensor(FunctPtr p) : getValuePtr(p) {
	}

	float getValue() {
		return getValuePtr();
	}

private:
	FunctPtr getValuePtr;
};

SensorType_pi piSensor;
SensorType_e eSensor;

GenericSensor sensors[] {
		{std::bind(&SensorType_pi::getValue, &piSensor)},
		{std::bind(&SensorType_e::getValue, &eSensor)}
};

void setup() {
	Serial.begin(115200);
	delay(1000);

	for (auto s : sensors) {
		Serial.println(s.getValue(), 4);
	}
}

void loop() {
}

Output:

3.1416
2.7183

here is an example with classes.

t's not too difficult to grasp and there is no need to bind member functions nor pass pointers around. You just let the compiler decide what is the correct member function to call.

We have a base class Sensor. A sensor has a label and a value.
There is a pure virtual function that returns the sensor's value which derived classes override to do what they need to do to fetch the sensor's value and return it.

I provided 3 basic subclasses, similar to what @gfvalvo did with mathematical constants (cool idea).

Then there is an array of instances of the different sensors. The array type is Sensor as it's a collection of specialised Sensors. The beauty of polymorphism is that when you call getValue() on one of the array's item, the compiler is smart enough to generate code that will find out exactly what subclass is involved and it will call the method defined for that instance.

class Sensor {
  public:
    const char * label;
    float value = 0;
    Sensor(const char * name) : label(name) {}
    virtual float getValue() = 0;  // Pure virtual, override in subclasses, use Runtime polymorphism
};

class piSensor : public Sensor {
  public:
    piSensor(const char * n) : Sensor(n) {}
    float getValue() {value = 3.141593; return value;}
};

class eSensor : public Sensor {
  public:
    eSensor(const char * n) : Sensor(n) {}
    float getValue() {value = 2.718282; return value;}
};

class goldenSensor : public Sensor {
  public:
    goldenSensor(const char * n) : Sensor(n) {}
    float getValue() {value = 1.618033; return value;}
};

Sensor* sensors[] = {new piSensor("Pi"), new eSensor("Euler's number"), new goldenSensor("golden ratio")};
const byte numberOfSensors = sizeof sensors / sizeof * sensors;

void setup() {
  Serial.begin(115200); Serial.println();
  for (byte i = 0; i < numberOfSensors; i++) {
    Serial.print(sensors[i]->label);
    Serial.print(F(": "));
    Serial.println(sensors[i]->getValue(), 6);
  }
}

void loop() {}

Running this with the Serial monitor set at 115200 bauds will print

Pi: 3.141593
Euler's number: 2.718282
golden ratio: 1.618033

may be this helps demystify this inheritance and polymorphism concept.

have fun

PS/ the for loop could be written using C++ range based for loop (in which case you don't need to deal with indexes nor need a variable to hold the count of items in the array).

  for (auto& aSensor : sensors) { // iterate through all sensors
    Serial.print(aSensor->label);
    Serial.print(F(": "));
    Serial.println(aSensor->getValue(), 6);
  }
1 Like

thank you both for the examples :slight_smile:

i think i understood inheritance but i cant see a good case in my particular case because it isnt as easy as creating one sensor object per sensor, for example the BME680 which would be one class has actually 7 sensor values, and i have internal function which need also to access the particular sensor values and do stuff with it (thats why i thought a seperate class to index them would be best)
in the end i want one bme680 class which does "everything" bme680 related but outputs the different values (getTemperature,getHumidity etc) but i also have additional classes which for example need to get getTemperature in an "universal" fashion (because each actual sensor has different number of sensor values etc) (for example to setup ioTWebConf Parameters and give each one the specific name like "BME680 Temperature") and i dont know how i can combine my particular case with inheritance

also because of the all in one bme680 class i dont know if it really makes sense to create a abstract class with pure virtual function since each sensor has its own implementation anyway
i just see this being useful if there are actually functions which are common amongst the sensors

tho i kinda still like the inheritance idea because of future proof ease of additions to all sensors and maybe i just dont see usecases right now to do the job (like setting up iotWebConf parameters for each sensor value and since the parameters are indexed, the sensor values probably also need to be without making it way more complex)

but i think i will try the inheritance route and see where i end up :slight_smile: thanks so far guys

maybe more about the project: the plan is to make one "base" to use it for many iot applications and sparkle it with Sensor/Outputs/Routines/Extras "modules" which can be combined with setter/getters in the "project loop/setup" like for example:

MinMax.setMinMax(BME680.getTemperature())
Display.setMin(MinMax.getMin())

Did you check out Adafruit as I suggested?

yes i did, tho i understand just half of it and this actually seem way more "universal" than it needs to be, i actually just wanna hide the specific sensor library stuff in a class to make it easy combinable like in the example above, i just need to come up with a good way to combine my "modules" (the problem im stuck right now is handling iotWebConf Parameters mostly tho i think its really nessecary to index the different values, specially if i use multiple sensors like 2 BME680s)

Is it better to have structs like the Adafruit Library uses? i wonder about processing time 1. loading a struct into current scope and deal with it VS 2. getting each variable via get function into the current scope

And is there a explicit advantage of using virtual methods? i dont think i got the concept right... since each derived class can add own methods, why not have multiple derived classes add the same named method without declaring it as virtual in the baseclass? (in my mind this just adds another layer to maintain in the case of having all functions virtual)

https://www.learncpp.com/cpp-tutorial/virtual-functions/

Well i still just see this being useful if there is A. a base class implementation OR B. there are actually multiple layers of inheritance so the most derived function gets used, is that right?

in any other case why even bother creating a virtual functions if derived classes can just add a common named method? (or is this just a best practise kinda thing?)

for the actual program i changed things around to make each class (additional functions) as independent as possible, which is i think the best in my case and for maintainability, they just get linked manually (with set and getters) in the "project routine" i think this is the easiest approach insead of linking them inside the classes (manual linkage is totally fine since for different sensors etc i also create a new "project class" which can combine different optional classes)

The usefulness of polymorphism is illustrated by @J-M-L's example in Post #10.

Of course, since it's your project, you're free to implement it however you like.

Hmm yes i get the examples but the example J-M-L is a great example of what i mean, you would end up with the same function of things even if you dont have the virtual base class method (atleast if i understood things right, please correct me if im wrong) this just seems to be "really" useful with multiple layers of inheritance beside being easier to read/understand if we take a look at the base class

atleast so far i dont have a common method for multiple sensors, and i also dont have multiple layers of inheritance, it would be just 1 layer (2 with base class), so atleast i think the easiest thing todo is leave inerheritance completely out if those 2 things dont change
but if i come up with common methods i will probably end up with inheritance later on, thanks for the headsup anyway :slight_smile:

It depends where you put your abstraction. Is it the physical sensor or is it what the sensors measures?
For example You could have 7 instances of a sensor class each targeting the same hardware.
(Not saying this is the best idea - but this is just to think out of the box)