Hi folks! First topic here
I would like to make visible a set of components stored in a juce::OwnedArray. I tried to iterate inside the array and make visible each component, even in the resize() method. But when I run the app, components are not visible and when I try to risize it complains: Exception thrown at 0x00007FF940F55D78 (msctf.dll) in ComposerController.exe: 0xC0000005: Access violation executing location 0x00007FF940F55D78.
MainComponent::MainComponent()
{
setSize(1024, 768);
// Create a fader component and add it in the array
Fader fader("cc11");
fader.tabId = 1;
fader.ccNumber = 11;
fader.ccValue = 50;
faders.add(&fader);
// make visible all the faders in the array
for (Fader * f : faders) {
addAndMakeVisible(f);
}
}
// set bounds for all faders in the array
void MainComponent::resized()
{
for (Fader * f : faders) {
f->setBounds(20, 90, 200, 300);
}
}
You are adding stack allocated Faders into the OwnedArray, which is not going to work. You need to instead heap allocate the faders and put those pointers into the OwnedArray.
Yes, you could do it with std::unique_ptrs but that seems to me a bit redundant, since the object ownership would be immediately transferred from the unique_ptr to the OwnedArray.
edit : Anyway, for completeness, the way to do it with unique_ptrs :
auto fader = std::make_unique<Fader>("cc11");
fader->tabId = etc...
faders.add(std::move(fader));
That would be more āmodern styleā, but wouldnāt really change much how it all works.
// here "faders" would be std::vector<std::unique_ptr<Fader>> faders;
auto fader = std::make_unique<Fader>("cc11");
fader->tabId = etc...
faders.push_back(std::move(fader));
yes, it works with both unique as well as shared_ptr. (havenāt tried weak_ptr)
iām telling you that because sometimes you might get into situations where while a certain vector of components might conceptually be the owners of those components you want to have another pointer to it somewhere else. alternatively you could reference or point to a unique_ptr and get the same effect, but that essentially makes it ānot unique anymoreā which might feel code-aesthetically unpleasant
I would advise against using shared_ptr unless youāre 100% sure you need a shared ownership model. The fact that you use the term āreferenceā is a pretty good hint that your ownership model is not shared.
Having a unique_ptr<T> that is referenced elsewhere as a T* (or WeakReference<T> if there is potential for dangling) is a perfectly valid approach, and is much easier to reason about than the same solution using shared_ptr all over the place.
aight. donāt wanna argue about that in detail, but just wanted to point out that smart pointers are generally usable in this scenario but with slightly different approaches in mind for basically the same outcome
Iāve now managed for many years without almost ever using std::shared_ptr. Using that is really a minefield that isnāt obvious at first but can hit you in the wrong spot at the worst possible moment. There are some exceptional circumstances where shared_ptr may be required, but those are very rare.
i had no obvious problems with shared_ptr yet and everytime someone discusses that with me it seems that the only argument is that shared ownership is bad, but i donāt find that very significant, because even when using shared_ptr there is always a main place for the object and some 2ndary places that will be destroyed before the main place later. especially in components that is a clear hierarchy. the advantage of shared_ptr is you can send them around by copy but the underlying obj will still be the same so you canāt accidently copy that obj and donāt need to specify references all the time