Book or tutorial suggestion for


#1

Hi guys,

I am really confused with multiple inheritance. I mean I am a begginer and I've learned a lot of things from Juce too, but when it comes to inheritance I am so confused. I want to learn about composition too.

Is there any book i can read from or any tutorial which explains it in detail (inheritance and composition) ?

I want to learn as fast as possible because in the end of May i should have finished the project i've started ( which has a lot of classes that necessary should inherit from each other i guess ).

If you know something please leave a link below.

Thanks! :)


#2

What don't you understand in these concepts ? There obviously are many sources of information on the subject and Jules has even set up a list on this very web site (http://www.juce.com/learn/learning-c).

As an example the explanations given in http://www.cplusplus.com/doc/tutorial/inheritance/ look pretty clear to me.


#3

thanks for the links, i will have a look at them now...

What I don't understand is this :

I hace 3 classes.

1- Class MainComponent ( where class A and class B appear).

2- Class A ( I have a Slider here and want the value of the slider to be shown in the label of the class B ).

3- Class B ( Here is the Label where should appear the value of the slider in class A).

Both of these classes A & B appear on the MainComponent class and there in no problem...The problem is that I don't know how to make the value of the slider appear on that label.

I can make it work inside a class where there is a slider and a label, but not in different classes which are separated with a cpp and header file each of them.

I took this example to make it clear for you because i have a lot of more cases where i should inherit from.

If you wan't i can pass some code in here so you can see by yourself and give me an idea about it. I mean the codes of the slider and label class which are not long.

Anyway i'll be happy if you helped me only with this example i told you. :)


#4

Here are the codes in case you want to help me understand this...


#ifndef TEST_H_INCLUDED 
#define TEST_H_INCLUDED 
#include "../JuceLibraryCode/JuceHeader.h" 
class ComponentA : public Component, public Slider::Listener 
{ 
public:ComponentA()
    :slider (Slider::LinearVertical, Slider::NoTextBox)     
{         
addAndMakeVisible(&slider);    
slider.setRange(0.0, 100.0, 1.0);
slider.setValue(80.0);       
  setSize(400, 120);   
  }     
~ComponentA(){}    
 void paint(Graphics& g){       
  g.fillAll(Colour(5, 5, 5));     
}     
void resized(){            
      slider.setBounds(10, 10, 20, 80);        
      }    
 void sliderValueChanged(Slider* slid){       
  if (&slider == slid)         {       
      label.setText(String(slider.getValue()), sendNotification);       
  }    
 }             
 Slider slider; 
private:     
}; 
class ComponentB : public Component 
{ 
public: ComponentB()       
   {         
addAndMakeVisible(&label);      
 setSize(400, 50);    
 }    
 ~ComponentB(){}    
 void paint(Graphics& g){     
    g.fillAll(Colour(5, 5, 5));   
  }    
 void resized(){        
          label.setBounds(10, 10, 60, 30);        
      }           
   Label label;
 private:        
   }; 
#endif  // TEST_H_INCLUDED

#5

Probably it would be interesting for you to familiarise yourself with the Observer pattern. This is a way of having different components in different classes notify one another about value changes and other events.

Try this:

1. Let the ComponentB derive from Slider::Listener (and not ComponentA). Your Component A contains the slider itself, while Component B contains the label, which is the one that should "observe" or "listen" to changes of the slider and react to that.

2. Move the sliderValueChanged method to the listener as well.

3. In ComponentA, you should tell the label to notify its listener about value changes, by doing this:

label.addListener (componentB);

Hope it helps


#6

I tried the way you said and again it doesn't work. :/

 


#7

My general advice would be to study C++ and the JUCE library a bit further. Pick up a recommended book on C++. Learn to debug your code with patience. You could also ask your question on Stack Overflow.

You might also want to look at std::function and lambda's as an alternative to using listeners. These are features introduced in C++11. 

However if you follow Timur's advice you should be able to get it working... 


#8

thanks for the advice. I guess now my only choice is to write all the codes in one class in order to make my project work, otherwise i think i'm not able to finish my project in time.

If anyone of you tries that example with the slider and label to show the value of the slider at the class where the label is, please let me now. :)


#9

Here's one way that you can do it.

https://github.com/JordanTHarris/GeraldsClassTest

The way I did this was I created an instance of ComponentA and ComponentB in MainContentComponent. I then used the public members from both (slider & label) to communicate with each other.

For instance, I would do something like this in MainContentComponent::sliderValueChanged():

if (&ComponentA.slider == slider) {
componentB.label.setText(String(componentA.slider.getValue()), sendNotificaiton); 
}       

Just take a look at my code and see if that works for you. I basically just used MainContentComponent to communicate between the two other classes. Another way I could have done this (or at least I think) is I could have created an instance of ComponentA in ComponentB, made ComponentB a Slider::Listiner, and did basically the same thing except the code in ComponentB::sliderValueChanged()
 would be more like this:

label.setText(String(componentA.slider.getValue()), sendNotificaiton);

I'm sure the way I did it isn't the best, but it works. I'm new to JUCE too (like 1 week new) and I'd love to know what other people are doing.


#10

Thank you very much. :slight_smile:


#11

No problem man. Hopefully that helps you understand a little about classes and how to communicate between members of a class. From what I understand, your problem isn't about inheritence. Inheritance is important to understand though, so you should definetely gain as much knowledge as you can.


#12

Hey Gerald,

So I was having a problem with "communicating" between classes and I did some research and found a way that you can do it with references. So say you want to do a two-way communication between class A and class B. You can create a reference object of class A in class B and vice versa. Then you can pass the actual class (in the MainComponent) as a reference in the other classes contructor. Here are some examples, and I'll call them ObjectA and ObjectB:

 

Edit: Apparently this code is all kinds of wrong (read Jules's comment below).

In class A (ObjectA):

class ObjectA {
public:
    ObjectA (ObjectB& objectB)
        : myObjectB{ objectB }
    {}

private:
    ObjectB& myObjectB;
};

 

In class B (ObjectB):

class ObjectB {
public:
    ObjectB (ObjectA& objectA)
        : myObjectA{ objectA }
    {}

private:
    ObjectA& myObjectA;
};

 

In MainComponent:

class MainComponent {
public:
    MainComponent ()
        : objectA{ objectB },
          objectB{ objectA }
    {}

private:
    ObjectA objectA;
    ObjectB objectB;
};

Then, you can use ObjectA in ObjectB like you would if you used it in MainComponent, and vice versa. I can't believe it took me so long to understand that, but it becomes essential and I'm really glad I learned it.


#13

Just in case anyone tries following this advice, I should point out that for such a small code snippet, there are a lot of mistakes!

Apart from the basic syntactic errors, the first thing that may confuse people once they've fixed that are that you've given the two objects copies of each other, not references or pointers (which would actually result in an infinite loop during construction).

And more importantly, even if you fix the code to use references and get it all to compile/run, then during construction one of the objects would have a reference to a not-yet-constructed instance of the other one, so any code that attempted to use the other object at that point would go horribly wrong. And likewise on destruction, at least one of the classes would have to be deleted first, so the other would still be left with a dangling pointer for some period of time.

If two objects need references to each other, then at least one of them would need to use a pointer, not a reference. Start it with a nullptr, and then assign the other object to that pointer only after everything has been fully constructed. You have a messier problem on deletion, because you need to nullify the pointer when its target is deleted.

..so in general, having objects with mutual references is a bad thing! It's usually a sign that you've deisgned something wrong and need to find a different way to structure your data so that dependencies only point in a single direction.


#14

Thank you for that Jules! Wow, I really messed up the syntax didn't I? Lol. I probably shouldn't try to write code examples with my phone anymore. I tried to fix it. As you can tell, I'm really just finding my way around references and pointers. I must say, using JUCE has been the best way of learning programming principles and practices though, because I can actualy put them to use in "real world" problems. I haven't even tried doing a two way communication like this, but in my mind I thought it would work. Man I'm feeling dumb right about now. Sorry about that! I'm just trying to help out another newcomer. :) I guess bad advice is worse than no advice though.

Anyways, thank you for correcting me and explaining that so well. I had not even thought about all of that. I should definetely do some more reading on using pointers and references. By the way, does communicating between objects like this have a name, like a design pattern or something? I'm just wondering how I can search for resources on this sort of thing. You have given me quite a bit to think about.

The way I'm doing it in my drawing app I'm trying to make seems to work, but it's not a two way communication. I really should have tried it before I tried to give advice. :\


#15

I would never blame somebody to take time to help in a open source community. The reader must have noticed that you are not experienced and such moderate your snippet. When i started to learn programming from scratch i did a lot of mistakes following bad advices (specially concerning optimization). But it was never the case from threads with newbies but mainly in talks from self proclaimed experts. But that’s true that personnaly i almost test everything hardly before to give an opinion :wink:


#16

Thank you for everything everyone :P. Even that I didn't try your example Jordan, no problem man for the bad advice. :D ;)

Actually i have stopped developing my program because i run out of time.

Maybe after some days i will post my program in here as a demo so everyone can use it and why not to give me feedback for everything.

I was trying to build a software where a user can create music in the simpliest way possible. Actually I have experince in producing electronic music, so I knew what was necessary to build in my software. This was just a project with 50 % point for the last exam in software engineering at  the university where i study.

I achieved a lot of thinks, but i wasn't able to create the editor of the notes and I didn't have time to make the pugin load so the user can play it...I mean to play any synthesizer that the user may have installed in his computer. This are the most important things for someone to create music, but anyway i don't want to say that I failed to complete my program :P. I am a beginner so its not a big deal. :)

I am showing you only a few pictures today and as I said after some days i will post my demo so you can give me feedback.

Don't forget that it was my first time programming and using Juce platform too. Only in two months i did all this. :)

Thank you everyone.

Here you have some pictures....

 

 

 

 

Here at the pictures i doesn't look that good, anyway I'm going to post it as a demo too after some days. ;)


#17

And sorry for my english too. :P


#18

Hey Jules, I think I understand why that wouldn't work now. So how would you recommend communicating between two objects? Or would you just not do that at all? It seems like it would need to happen sometimes. I really appreciate your reply and it's made me want to do some research on how you can do this sort of thing, although I'm coming up dry so far.


#19

Do you think that using member functions (maybe like ObjectA::setB(B& objectB) and ObjectB::setA(A& objectA)) to pass references of each other would work? Then in those functions, assign those reference argumens to the object living in each class. And perhaps call those functions in MainComponent's constructor after the two objects have been constructed. Idk, I'm thinking that could fix the construction problem from my examples earlier. I'm not sure about the other problems though.

I've been trying to think of the best way to do something like this all day. I'm not coming up with much, but your comment really got me thinking about it, which to me is a great thing. Maybe this is sort of thing is a bad design decision anyways, but I would really like to learn more about ways you can use objects together. I've come across that problem so many times lately. 


#20

You seem to be making a big deal out of this question! It's all just a case of passing pointers around and being careful about ownership. 

There are many ways you can give classes a pointer or reference to something else, you just need to think about what's appropriate based on what you're trying to do.. Maybe also look at things like Component::SafePointer, WeakReference, SharedResourcePointer, etc