2

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);
    }
}
}
harry97uk
  • 33
  • 5
  • 1
    Can you show the declaration of the `FilePlayerGui`class? I'm sure that it's been declared as non-copyable. The simplest approach is almost certainly going to be to hold pointers to those objects (probably with a JUCE `OwnedArray` object to manage lifetimes for you. – bgporter Jan 05 '18 at 02:20

1 Answers1

0

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.

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • It comes up with this error "Copying array element of type 'FilePlayerGui' invokes deleted constructor" when I do this – harry97uk Jan 04 '18 at 22:35
  • 1
    @harry97uk I've updated my answer, but as you can see from the answer I'm a little salty about it. This isn't a healthy question. You're trying to subvert the intended use of `FilePlayerGui` which almost certainly means that you will continue to run into issues if you proceed down this path. – Jonathan Mee Jan 05 '18 at 13:47
  • Thank you for the information, it has definitely helped me out a lot! I understand what the problems are but for now I'm going to just create two instances of the class so I can carry on with the work and resolve this issue properly with my university professors, thank you for your help though! – harry97uk Jan 05 '18 at 17:05
  • @harry97uk If this solved your problem I'd suggest accepting the answer. Otherwise writing your own answer and accepting that may be helpful to future readers. – Jonathan Mee Jan 05 '18 at 18:16