Give a child component access to its parent's private variables


#1

Just wondering what's the best advice on how to do this...any tips very appreciated!

I'm coding a piano roll.

Have got the background sorted out, and now looking at adding note components.

The note components are their own component class, and will be dynamically created when needed.  These components need to know quite a lot about the size and state of various parts of the parent background class. 

I'm quite a C++ noob, so not too clear about this, but i'm thinking the best option might be to make the note components a friend class of the background parent.  Does that sound ok?  

If that's the way to go, can someone give me a quick tip on the syntax on how to dynamically create these note components and declare them friends of the parent?

 

 

 

 


#2

Disclaimer, I don't claim to be an expert either ;)

Could you simply pass a reference to the parent to the note component when its been created?

void ParentComponent::createNote()
{
      Note* note = new Note(this);
      (.....)
} 

 


#3

These components need to know quite a lot about the size and state of various parts of the parent background class. 

Are you sure this is the right architecture? Intuitively, I'd say it should be the other way around: the parents should know stuff about their children, resize them as needed etc., and the children should be the more generic/agnostic ones.


#4

That only gives access to the public variables, though, doesn’t it?

I’d rather leave them private and only give access to the child components.


#5

Yeah that sounds like it might be the way to go. Will take the resizing code out of the child and put it as a function in the parent. Sounds like it’d work well. Cheers.


#6

i usually do the forward declaration as well.

 

all you need to do to access the private data is add some setter and getter functions


#7

Put Rory's and Timur's posts together...

If the parent owns the child (i.e. child is destroyed in the parent's destructor), then it is safe to have the backlink. Otherwise you get dangling pointers.

But use that backlink only to notify the parent, that something in the child has changed (so called subject-observer pattern). The parent will do all resizing, placement and repainting. This is useful, if e.g. the mouse events are handled in the child objects (like the midi event is dragged).

Especially when you use polymorphism in the children, the children shall not do anything in the parent, because you multiply the chances for errors...

 


#8

If the parent owns the child (i.e. child is destroyed in the parent's destructor), then it is safe to have the backlink. Otherwise you get dangling pointers.

This is why people invented smart pointers. Dangling pointers can be safely avoided by properly using std::unique_ptr, std::shared_ptr, and std::weak_ptr.


#9

Right, didn't want to go into every detail ;-)

If the ownership is clear, would you still use smartpointers? Or would this be considered overkill?

And what is your opinion on juce::WeakReference and Component::SafePointer?

I used them because I had confusions about the c++ dialects, you remember... And now they are in several places in my code. Would you recommend to change them into std::weak_ptr?


#10

I guess it's a matter of taste and personal preference. I am personally more used to the standard C++ ones and I don't care about C++98 compatibility except for code that goes into the JUCE framework itself... but you may have different preferences!

And yes, I would always prefer smart pointers over raw pointers. The default choice in simple cases is std::unique_ptr, which actually does not have any runtime overhead over a raw pointer, but does clean up after itself!


#11

I did a little reading on the cpp reference, sounds like I should make a habit of using those pointers.

One last question, I read, that the weak_ptr converts into a shared_ptr to avoid the object being deleted while being used. Does this work with unique_ptr too? I.e. that the deleter of the unique_ptr is called after the weak_ptr is finished?

Thanks for the hints...

P.S: sorry bananas, didn't mean to hijack your thread...


#12

No, weak_ptr is not going to work with unique_ptr, only with shared_ptr.

As the name suggests, a unique_ptr should be a unique pointer to an object, i.e. no other place should have a pointer to that object. So having also a weak_ptr to it would be wrong.


#13

Ok, that makes sense. Thanks for clearing that up...