Input does not work in Array of Instances (SOLVED)

Havin all Instances as separate variable works fine
Having them in an array somehow breaks input
would be nice to be able to iterate through the instances

separate (works):

Loop    track1(D30, D6,  1, buffer1),
        track2(D26, D7,  2, buffer2),
        track3(D22, D8,  3, buffer3),
        track4(D18, D12, 4, buffer4),
        track5(D17, D13, 5, buffer5);

int main(void)
{
    track1.ResetTrack();
    track2.ResetTrack();
    track3.ResetTrack();
    track4.ResetTrack();
    track5.ResetTrack();

    while(1) {
        track1.UpdateButton();
        track2.UpdateButton();
        track3.UpdateButton();
        track4.UpdateButton();
        track5.UpdateButton();
    }
}

array (dos NOT work):

Loop tracks[5] = {   Loop(D30, D6,  1, buffer1),
                    Loop(D26, D7,  2, buffer2),
                    Loop(D22, D8,  3, buffer3),
                    Loop(D18, D12, 4, buffer4),
                    Loop(D17, D13, 5, buffer5) };

int main(void)
{
    for (Loop track : tracks) {
        track.ResetTrack();
    }

    while(1) {
        for (Loop track : tracks) {
            track.UpdateButton();
        }
    }
}

The class initializer

Loop(Pin button1Pin, Pin button2Pin, int no, float* buf) {
        buttonLow.Init(button1Pin);
        buttonTop.Init(button2Pin);
        buttonLow.Debounce();
        buttonTop.Debounce();
        loopNumber = no;
        buffer = buf;
    }

Okay, the error seems to be the foreach loop somehow
this works

for (int i = 0; i < 5; i++) {
    tracks[i].UpdateButton();
}

okay, apparently the issue is that its not used as a pointer
this works
dont know what exactly is the difference, but guess that (Loop track : tracks) creates a new instance while (Loop &track : tracks) points to an instance

for (Loop &track : tracks) {
    track.UpdateButton();
}

Correct, the first syntax creates copies by value of each object in the array while the second syntax (with the reference declarator &) iterates over references to the existing objects in the array without creating copies. It wasn’t working before because you were calling the methods on temporary copies of the objects instead of the original objects.

If you have a class type that’s intended only for static or stack allocation rather than heap allocation (like I am assuming the Loop class is) and you want to prevent accidentally creating copies by-value, you can explicitly delete the default-generated copy constructor and assignment operator implementations when declaring the class, then compilation will fail if you end up accidentally writing code that copies by value (as per the first syntax without the &)

Mutable Instruments stmlib has a nice macro for this which simply declares the copy constructor and assignment operator without providing any implementation (same end result) and is used all over the codebase(s). However I prefer to do it explicitly using the delete keyword:

class Loop
{
    public:
       Loop(Pin button1Pin, Pin button2Pin, int no, float* buf);
       // ..
       // ..etc

    private:
       // Explicitly delete copy constructor and assignment operator
       // to prevent accidental copy-by-value
       Loop(const Loop& a) = delete;
       Loop& operator=(const Loop& a) = delete;
};

why would you wanna create copies? is there any use case for that?

not entirely sure what the difference between static and heap allocation is, but reading that static is a fixed lifetime allocation this sounds like the wanted one
(the main creates 5 Loop instances that are being used forever and also need quick data access (which was stated that static is better for) as they also need to return the current audio samples)

would you put the copy constructor like this into the header file or do you split it up and also have it in the implementation (cpp) file?