Funtion pointer array in a class

Is it possible to build the functionality of the below code into a class object.
I need to invoke separate instances of a function w/ different params simultaneously. In my attempts my compiler started swearing at me ..

1
2
3
4
5
6
7
8
9
10
11
12
13
  		void effect_1(int tdelay_1) {
		digitalWrite(25, LOW);
		digitalWrite(26, HIGH);
		}

		void effect_2(int tdelay_2) {
		digitalWrite(26, LOW);
		digitalWrite(25, HIGH);
		}

		void (*effect_funct_array[10])(int);
		effect_funct_array[0] = effect_1;
		effect_funct_array[1] = effect_2;
bdrenchley wrote:
I need to invoke separate instances of a function w/ different params simultaneously.

Not quite sure I understand the requirement there. Or why a class containing function pointers would help.

Making such a class should be possible, though (haven't included methods for removing functions etc):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <vector>

using FuncPtr = void(*)(int);

class SomeContainer
{
private:
    std::vector<FuncPtr> m_functions;
	
public:
    void AddFunction(FuncPtr someFunction)
    {
        m_functions.push_back(someFunction);
    }
	
    void CallAllMethodsWithValue(int v)
    {
        for (const auto& f : m_functions)
        {
            f(v);
        }
    }
};

void PrintValue(int v)
{
    std::cout << v << std::endl;
}

void PrintDoubledValue(int v)
{
    std::cout << v * 2 << std::endl;
}

int main(int argc, const char* argv[]) 
{
    SomeContainer someContainer;
    someContainer.AddFunction(PrintValue);
    someContainer.AddFunction(PrintDoubledValue);
	
    someContainer.CallAllMethodsWithValue(42);
	
    return 0;
}


THANKS MrHutch:
Your method bears investigating ..
Unless I'm misunderstanding instantiating different class objects would afford same functionality w/ different params concurrently ..
This is what I've cloned from various examples I've reviewed .. but it presents an issue.
I can't seem to determine the proper syntax to invoke the functions via the array function pointers. The compiler complains about scope. NOTE: I've been informed it's best practice for the defs in the class to be private but the compiler complains if so in this instance. Perhaps it's hinting at other issues in my code .. they say best way to learn is make mistakes .. ;-)

"error: 'effect_funct_array' was not declared in this scope
:(Strip1.*effect_funct_array[pntr_1])(tdelay_1,0,0)"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int pntr_1 = 0;
int tdelay_1 = 0;
// Led Effects Class
class effects {

	public:
	typedef void (effects::*pt2effects)(int,int,int);
	pt2effects effect_funct_array[10];

	effects () {
		effect_funct_array[0] = &effects::effect_1;
		effect_funct_array[1] = &effects::effect_2;
	}

	void effect_1(int arg, int arg2, int arg3) {

	}

	void effect_2(int arg, int arg2, int arg3){

	}

};

	effects Strip1;
	effects Strip2;

int main(){
	(Strip1.*effect_funct_array[pntr_1])(tdelay_1,0,0);
return 0;
}
Last edited on
Yeah, the syntax is going to get messy here.

In addition to specifying which instance you're grabbing the method from, you also need to specify which instance you're _calling_ the method on. This results in some ugly syntax:

(Strip1.*(Strip1.effect_funct_array[0]))(0,0,0);

I'm getting the impression that function pointers aren't really what you want here and the solution you're looking for is probably much, much simpler.

If you give some further context, I might be able to help more. For now, I'll try to address some of the things you mentioned.

dbrenchley wrote:
Unless I'm misunderstanding instantiating different class objects would afford same functionality w/ different params concurrently ..

Yes, sort of.

You can create different instances that may have different state, depending on how your write your classes. What you've actually described, in my opinion, is more aligned with the behaviour of methods. You could call the same method twice with different arguments, for example.

Classes are usually a little more involved. They'll typically have some internal state and model something in your program, like complex objects that cannot be represented through the fundamental data types.

'Concurrently' is a funny term here. Concurrency is a whole concept in itself in programming and I don't think this is what you're referring to. It describes code that is executed across multiple threads. For example, the following code example would not be concurrent:

1
2
myFirstInstance.DoStuff();
mySecondInstance.DoStuff();


Although these calls could occur in the same frame, they're still synchronous or serial. The first DoStuff call executes in its entirety before the second. Though this doesn't represent concurrency in the typical programming sense, I think it might be more aligned to what you're looking for. Again, further context might help here.

dbrenchley wrote:
I've been informed it's best practice for the defs in the class to be private but the compiler complains if so in this instance.

Yes, what you're broadly describing here is the concept of encapsulation. It's often a good idea to keep class members private and expose functionality via public interfaces.

See my example in the second post. I have a vector as a private member. I cannot directly access this from outside of the class. However, I expose the limited functionality that I do want to offer via a AddFunction method. This way, I'm limiting what can be done to the class from the outside world.

There are numerous benefits to this (have a Google) but the most significant is probably the preservation of important internal state - imagine I had a method that relied on some state in the class that I made public and could be modified from anywhere. How can I reliably guarantee that the state is good and code outside the class hasn't unexpectedly meddled with it?

Hope this helps.
Thank you so much for taking the time and effort .. truly appreciate it ..
"concurrent" as I typed it I knew it was a bad word ..
and your discussion regarding state preservation describes my ultimate goal.

I'm developing a real time interrupt driven application. The ISR's will have the same functionalities available with specific methods determined by machine state. Due timing issues there will be a priority hierarchy.

My interest in the use of class objects I believe will provide a means where a higher priority interrupt can interrupt a lower currently executing ISR, run the "same" method while preserving the variable states of the interrupted ISR.

BTW .. your code statement works .. I'll have to deal w/ the messy syntax .. less w/ my outlining above you believe there's a better means I should investigate.


another ? if I may ..

how do you return the address of an array pointer ?

*p = &myarray[0]

*p returns array content as I would expect ..
** p also seems to return the array content ..

I want to modify p from within a function(p) .. ??

I've so much to learn .. ;-)
Topic archived. No new replies allowed.