Initialising array in constructor

Hi,

this is my first post, so apologies if I make some mistakes posting

I have tried googling around, but maybe I found the answer and I didn't understand it, so I am asking you guys!

I have a fairly simple project:
three buttons, one piezo
when pressing one button, the piezo plays some notes

It works when doing in a "procedural" way, but I would like to be able to extend it using OOP, so I created two classes.
The first one is a Player class
It contains the algorithm to play the notes
The second one is a Songs class

Songs

Songs.h

class Songs{
  public:
	Songs(char title[]);
	int melody[];
	int tempo[];


};

Songs.cpp

Songs::Songs(char title[]){

	if (title == "sm"){
        //this bit here does not work...
        //compiler says: error: assigning to an array from an initializer list
	   melody = {
		NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0,  0, NOTE_G6, 0, 0, 0, NOTE_C7, 0, 0, NOTE_G6,
		0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7,
		0, NOTE_E7, 0, NOTE_C7,	NOTE_D7, NOTE_B6, 0, 0,	NOTE_C7, 0, 0, NOTE_G6,	0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0,

		NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0, NOTE_C7, NOTE_D7, NOTE_B6, 0, 0,
		NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0,  0, NOTE_G6, 0, 0, 0,
	  };
          
          //this bit here does not work, same as above
	  tempo = {
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
		9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
	  };


    }
}

The notes are defined in the Songs class, each one has a value

In my sketch, I want to do the following:

//initialisation is performed outside setup and loop
Song supermario("sm");
Player player;

When pressing a button, it should work like this:

//this goes in the loop
player.play(supermario.melody, supermario.tempo);

It seems like my problem is the array initialisation in the constructor given a certain parameter to the constructor itself.
Can someone point me in the right direction to achieve this?
I would appreciate to know as well if this is the right way of doing it, or there is a better approach.

Thanks in advance!

The only time you can initialize an array with all the elements in brackets like that is when it is first created. You can't assign to it that way. If you want to fill it in the constructor then you'll have to do it one element at a time.

myClass::myClass(){

   myArray[0] = 8;
   myArray[1] = 10;

   // etc...  
}

But really, why are you doing it like that? Do you really want the song to be hard coded into the class like that? That kind of takes away from the utility of the class if it is only good for one song. You might as well code it the procedural way.

What you could do is have the notes and durations in arrays defined in some other header or even in the sketch and pass them to the constructor just like you do the name. Then use memcpy to put them into the arrays in the class, or better yet just have pointers to the arrays in the class and let the class members point to arrays that live elsewhere.

Maybe something like this will work:

Songs.h

class Songs{
  public:
	Songs(char title[]);
	const int *melody;
	const int *tempo;
};

Songs.cpp

static const int sm_melody[] = {
		NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0,  0, NOTE_G6, 0, 0, 0, NOTE_C7, 0, 0, NOTE_G6,
		0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7,
		0, NOTE_E7, 0, NOTE_C7,	NOTE_D7, NOTE_B6, 0, 0,	NOTE_C7, 0, 0, NOTE_G6,	0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0,

		NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0, NOTE_C7, NOTE_D7, NOTE_B6, 0, 0,
		NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0,  0, NOTE_G6, 0, 0, 0,
	  };

static const int sm_tempo = {
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
		9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
	    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
	  };

Songs::Songs(char title[]) {
  if (strcmp(title,"sm") == 0) {
    melody = sm_melody;
    tempo =  sm_tempo;
  } else {
    // NO MATCHING SONG TITLE FOUND
  }
}

Make the data members 'private' and manipulate them in the constructor or add 'public' setter and getter functions?

Thank you very much everyone for you help!
I'll try your suggestions, see how it goes and let you know!

paahaa:
When pressing a button, it should work like this:

//this goes in the loop

player.play(supermario.melody, supermario.tempo);

Be warned that the 'player' object has no way of knowing how many notes are in the melody. I expect you will find that you have to get that value from somewhere and pass it to the player. The Songs object will have to store the number of notes because it is the only place that the value is easily determined.