Search code examples
c++arraysclassjuce

How can I initialise this class in an array?


I'm trying to make an array of class filePlayerGui and when I try to initialise it in the constructor it won't let me do so

class MainComponent   : public Component,
                    public MenuBarModel
{
public:
//==============================================================================
/** Constructor */
MainComponent (Audio& audio_);

/** Destructor */
~MainComponent();

void resized() override;

//MenuBarEnums/Callbacks========================================================
enum Menus
{
    FileMenu=0,

    NumMenus
};

enum FileMenuItems
{
    AudioPrefs = 1,

    NumFileItems
};
StringArray getMenuBarNames() override;
PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName) override;
void menuItemSelected (int menuItemID, int topLevelMenuIndex) override;

private:
Audio& audio;
FilePlayerGui filePlayerGui[2] {audio.getFilePlayer(0), audio.getFilePlayer(1)};



//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

The filePlayerGui comes up with this error "Copying array element of type 'FilePlayerGui' invokes deleted constructor". I have tried initialising it in the .cpp file that I'll down below but then it tells me that I need an array initialiser

MainComponent::MainComponent (Audio& audio_) : audio (audio_)
{


setSize (500, 400);
addAndMakeVisible(filePlayerGui[0]);
addAndMakeVisible(filePlayerGui[1]);
}

MainComponent::~MainComponent()
{

}

 void MainComponent::resized()
 {
filePlayerGui[0].setBounds (0, 0, getWidth(), 40);
 }

   //MenuBarCallbacks==============================================================
 StringArray MainComponent::getMenuBarNames()
{
const char* const names[] = { "File", 0 };
return StringArray (names);
}

PopupMenu MainComponent::getMenuForIndex (int topLevelMenuIndex, const String& menuName)
{
PopupMenu menu;
if (topLevelMenuIndex == 0)
    menu.addItem(AudioPrefs, "Audio Prefrences", true, false);
return menu;
}

void MainComponent::menuItemSelected (int menuItemID, int topLevelMenuIndex)
{
if (topLevelMenuIndex == FileMenu)
{
    if (menuItemID == AudioPrefs)
    {
        AudioDeviceSelectorComponent audioSettingsComp (audio.getAudioDeviceManager(),
                                                        0, 2, 2, 2, true, true, true, false);
        audioSettingsComp.setSize (450, 350);
        DialogWindow::showModalDialog ("Audio Settings",
                                       &audioSettingsComp, this, Colours::lightgrey, true);
    }
}
}

Solution

  • Copying array element of type FilePlayerGui invokes deleted constructor

    Means that some variant this line is in the declaration of the FilePlayerGui:

    FilePlayerGui(const FilePlayerGui&) = delete
    

    Meaning that a FilePlayerGui cannot be copied: https://en.cppreference.com/w/cpp/language/copy_constructor#Deleted_implicitly-declared_copy_constructor

    There are workarounds, but you are skirting the author of FilePlayerGui's intent for the class. So the correct answer should stop here. Any use of FilePlayerGui should be done through the the classes audio member, using either: audio.getFilePlayer(0) or audio.getFilePlayer(1). (If this is the only member of MainComponent in all likelihood MainComponent should be eliminated.)


    If you want to know how to do bad things, which I would reject in any code review, you can either create filePointerGui as:

    1. FilePointerGui* filePointerGui[2] which would be intialized as:
    MainComponent::MainComponent(Audio& audio_) : audio(audio_), filePointerGui({ &audio.getFilePlayer(0), &audio.getFilePlayer(1) })
    

           Access would be performed as:

    *filePointerGui[0]
    

           Live Example

    1. reference_wrapper<FilePointerGui> filePointerGui[2] which would be initialized as:
    MainComponent::MainComponent(Audio& audio_) : audio(audio_), filePointerGui({ audio.getFilePlayer(0), audio.getFilePlayer(1) })
    

           Access would be performed as:

    filePointerGui[0].get()
    

           Live Example

    It's probably worth stressing once more this is bad code because it tries to outsmart the language and work around the intent of the classes design. But this is so you can do it.