Beginner: how to create component using 'new'

This is a very beginners question and I’m feeling ashamed I can not figure this out.
When I create a slider which is a member of my main component, all is fine.
But when I create this slider using the ‘new’ my application crashes.

This is what I do:

In MainComponent.h:

private:
  Slider* frequencySlider;

In MainComponent.cpp:

MainComponent::MainComponent()
{
    setSize (800, 600);

    frequencySlider = new Slider("SliderName");
    addAndMakeVisible (frequencySlider);
    frequencySlider->setRange (50, 5000.0);
    frequencySlider->setTextValueSuffix (" Hz"); 
}

void MainComponent::resized()
{
        auto sliderLeft = 120;
        frequencySlider->setBounds (sliderLeft, 20, getWidth() - sliderLeft - 10, 20);
}

The application crashes on the setBounds() in resize().
Any idea what I do wrong?

You should use ‘std::unique_ptr< juce::Slider>’ for this. And ‘frequencySlider = std::make_unique< juce::Slider>(“slider name”);’

But the best way is to avoid pointers on creating components. You only should use pointers if you really need to.

You’re calling setSize (which results in a call to MainComponent::resized()) before creating the slider, so you’re calling setBounds on the uninitialised Slider*, hence the crash.

Moving setSize to the bottom of your constructor should avoid crash.

3 Likes

Ahh, I knew I did something stupid. Thanks!

most likely an architectural problem or a language misunderstanding.

if your frequency parameter should always exist it should just be an object instead of a pointer.

Slider frequencySlider;

MainComponent::MainComponent() :
    frequencySlider("SliderName")
{
    addAndMakeVisible(frequencySlider);
    //..
    setSize(800, 600);
}

if you need it to be dynamic you can either do that by calling setVisible() on it when needed or by indeed making it a pointer, in which case unique_ptr is the best choice. it would look like this:

std::unique_ptr<Slider> frequencySlider;

MainComponent::MainComponent() :
    frequencySlider(std::make_unique<Slider>("SliderName"))
{
    addAndMakeVisible(*frequencySlider);
    //..

unique_ptr is useful if you wanna swap the component with another one later, or if it can be components of different types that derive from the pointer’s base class, or as part of a vector to enable a dynamic amount of components of some type.
careful with the methods setRange(), setTextValueSuffix(), and setValue(). If you ever make plugins these will become obsolete, because the so called parameter attachments tell the slider its properties already. beginners often try to keep it nice and simple by not immediatly jumping into a plugin project, but in turn learn some things that will be misleading later on in that process

1 Like