2

I'm new to C++, and have experience with other programmas languages, but I have a question: How can I access a list from a sub class, from the parent?

Here is my layout: TutorialApp.cpp with function TutorialApp::update() In that function I want to access the list mParticles2y from another class that list is made in: ParticleController.cpp, like this:

std::list<int> mParticles2y;

I've tried accessing the list like this [in TutorialApp]: mParticleController.mParticles2y.size() [to get it's size]

but that gives me this error:

call of an object of a class type without appropriate operator

So I dont really know where to go from here...

PS: I use mParticleController because that is state in my script:

ParticleController mParticleController;

I hope this is enough info.

PS: I'm not really sure this is called a class, or child, I use these terms because I know them from ActionScript [which works with classes in a similar way]

jleahy
  • 16,149
  • 6
  • 47
  • 66
laarsk
  • 862
  • 6
  • 17
  • 36
  • 1
    You will need to post your code. – Alok Save Oct 26 '11 at 15:10
  • Ok, here is the code from my TutorialApp.cpp: http://pastebin.com/req95dTP and the code from the ParticleController: http://pastebin.com/7S8t8b8n note that this is written using the Cinder library – laarsk Oct 26 '11 at 15:19
  • @laarsk: Why would anyone go through all of your code and fix it for you? Post a few lines that reproduce the error you are seeing, and you are likely to have a good answer in under 5mins. As it is, most will just gloss over and move one. We are volunteers, and you will have to provide something to pique our curiosity (or our vanity) in order to get answers. – sbi Oct 26 '11 at 15:26
  • Sorry for that, here is a better piece: http://pastebin.com/uCYT07p0 – laarsk Oct 26 '11 at 15:26

4 Answers4

1

Your code for the loop that has the errors should look more like this. It may not compile exactly since I can't compile it easily at the moment. This isn't the ideal way to go about it, but it is the minimal impact to your code. I would move this loop to the ParticleController class as a member function that returned true/false to indicate a hit. It would be better encapsulated that way.

    for(std::list<int>::iterator yit = mParticleController.mParticles2y.begin(), 
       std::list<int>::iterator xit = mParticleController.mParticles2x.begin();
       yit != mParticleController.mParticles2y.end() && xit != mParticleController.mParticles2x.end();
yit++, xit++)
   {
    if(
        (coordy >= *it) && (coordy <= (*it) + 40) &&
        (coordx >= *xit) && (coordx <= (*xit) + 40) 
       )
    {   
       mParticleController.removeTargetedParticles(i); //remove blokje
             score += 1; //score verhogen
    }

}

Wayne Tanner
  • 1,346
  • 11
  • 18
  • I have that, just forgot to copy it :) – laarsk Oct 26 '11 at 15:16
  • I took a look at your code. Without the header file for ParticleController it isn't possible to determine exactly what's wrong. Is the mParticles2y list public, protected or private? The call site looks ok. – Wayne Tanner Oct 26 '11 at 15:26
  • Ok, thanks! here is the header code from ParticleController: http://pastebin.com/QXaiwiWH – laarsk Oct 26 '11 at 15:27
  • Actually, that is the header for Particle. :) – Wayne Tanner Oct 26 '11 at 15:29
  • The problem is where you are calling mParticleController.mParticles2y(i). If mParticles2y were an array or vector you could use [i] to get the item at the ith index. Since it is a list you can't. Operator () is something different. I would suggest iterating through the list using stl iterators. Look up an examble of using list.begin()/list.end() to iterate. – Wayne Tanner Oct 26 '11 at 15:40
  • The code for the loop should look like: for(list:iterator it = mParticleController.mParticles2y.begin(); it != mParticleController.mParticles2y.end(); it++) { } – Wayne Tanner Oct 26 '11 at 15:42
  • I indeed assumed that a list would work the same as an array, but does this mean you can't remove a certain value from a list? For example the 3rd value in a list? – laarsk Oct 26 '11 at 15:42
  • As a side note, calling size() on a list is order N, as it has to go through the list and count the elements. You probably don't want to be doing that in code where you are doing hit testing. – Wayne Tanner Oct 26 '11 at 15:44
  • You can remove an element from a list, see the erase function. As above, you will need iterators to do it however. – Wayne Tanner Oct 26 '11 at 15:45
  • What does "order N" mean? (I'm not english so I dont know, and I'm not experienced with C++) But how does that iterator work then? From other scripting languages I'm used to an iterator being a number which is increased in a for loop. This might sound really stupid, but thats all I know. Maybe I should try to understand this example? http://www.cplusplus.com/reference/stl/list/erase/ – laarsk Oct 26 '11 at 15:49
  • That is a good simple example. For arrays and vectors, they can be accessed with an integer subscript since they are either an array or vector can be approximately treated as one. Lists on the other hand are a series of linked nodes. The array subscript operator isn't provided since it would have to start at the beginning and look for item number N everytime it was used. Order N refers to the fact that you would have to look at N items to get to the Nth one for a list. In a vector it is considered Order 1 since you can go straight to the item with the index of N. – Wayne Tanner Oct 26 '11 at 15:56
  • Ok, I'll try to understand that example and then return to my script. Thanks for the help and carefull explanation, I really appreciate that! – laarsk Oct 26 '11 at 15:59
1

Ok, so this is a shot in the dark, since your question, while very wordy, is short on code necessary to reproduce the issue.

You can only access public members (data or functions) of other objects. That is, in order to access mParticleController.mParticles2y, mParticles2y must be a public member of whatever type mParticleController is of.

Of course, public data member are frowned upon, and for good reasons. A class should represent an abstraction, and if you have a particle controller, it should implement everything necessary to control particles, rather than spilling its guts out in the public for everyone to sift through and take what they need.

This is called encapsulation, and one of the cornerstones of the object oriented paradigm.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • Ok, that sounds logical, but the weird thing is: MS Visual C++ 2010 Express puts the red error lines under this part: mParticleController, and not the list... or does that make sense? – laarsk Oct 26 '11 at 15:17
  • @laarsk: You will have to post a minimal piece of code that reproduces the error, if you want better help than my this. – sbi Oct 26 '11 at 15:19
  • Ok, I posted links to the code now: the code from my TutorialApp.cpp: pastebin.com/req95dTP and the code from the ParticleController: pastebin.com/7S8t8b8n note that this is written using the Cinder library – laarsk Oct 26 '11 at 15:20
  • @laarsk: Read again my last comment, please. I wrote "a minimal piece of code that reproduces the error". I did not write you should post links to tons of code for us to go through. Put in the effort required to come up with max. 20 lines of code reproducing the issue you are asking about, and I will have a look at it. But I will not look at all your code and sort it all out for you. – sbi Oct 26 '11 at 15:23
  • Ok, sorry, I kinda expected that. Ill cut out a better part now – laarsk Oct 26 '11 at 15:25
  • Here is a better piece: http://pastebin.com/uCYT07p0 That should be all you need, I think. All the declarations are done properly. – laarsk Oct 26 '11 at 15:26
  • @laarsk: No, it's not all I need. It's still not showing what type `mParticleController` is of, and it's not showing that type, so I can see the definition of `mParticles2y`. Anyway, this is the moment I give up on you. Have a nice day. – sbi Oct 26 '11 at 15:29
  • I've actually posted the type of mParticles2y in my start post: std::list mParticles2y; As for the type of mParticleController.. how do you mean "type"? – laarsk Oct 26 '11 at 15:33
  • @laarsk: If you do not know what a type is (for), you will need to read a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – sbi Oct 26 '11 at 15:44
  • I'm sorry @sbi, it's hard to know everything you are talking about, when I'm just starting with C++. Besides that I'm also not english which makes it even a bit harder. – laarsk Oct 26 '11 at 15:51
  • @laarsk: I understand that. (Both. I'm not a native speaker either.) However, in order to properly learn C++, you will have to read a book. – sbi Oct 26 '11 at 15:52
  • Yeah, I'll need to read more or get lessons. This little project I'm working on is actually a small school project, where I make a snake game in C++ [never touched this language before] and the Cinder library, and then give a workshop about it, togetther with 3 other persons, to 15 persons or something like that. So in this case I kinda had no preperation whatsoever. Not the best start, I know, but its a really nice start to get me enthousiastic about C++. [and it definitly works!] – laarsk Oct 26 '11 at 15:57
0

size is a method, you need to write size().

Dabbler
  • 9,733
  • 5
  • 41
  • 64
  • I have that, just forgot to copy it :) – laarsk Oct 26 '11 at 15:15
  • Well, even before I compile it, as MS C++ Express shows the red line so it means it wont compile. And I won't try. – laarsk Oct 26 '11 at 15:24
  • Ah, IntelliSense isn't always reliable. Please do compile, and be sure to paste the compile errors from the *output* window, not from the "error list" (or whatever it's called) that opens up by default. Only then will we know what the compiler is really complaining about. – Dabbler Oct 26 '11 at 15:27
  • Hmmm, that error output isnt really clear to me, it outputs a lot of error [while the script works fine without the posted for loop [http://pastebin.com/uCYT07p0 ]: http://pastebin.com/ZSzHFjJ4 – laarsk Oct 26 '11 at 15:31
  • That would be this: for( i = 0; i < (mParticleController.mParticles2y.size()); i++){ – laarsk Oct 26 '11 at 15:37
  • The parenthesis on the right side of the comparison are redundant, but I don't see an error... hmmm... – Dabbler Oct 26 '11 at 15:43
  • Yeah, I know, but its just to make sure C++ read the code correctly :P Better safe then sorry... I believe @WayneTanner is now explaining me that what I want should be done differently... – laarsk Oct 26 '11 at 15:46
0

The information you provide is somewhat ambiguous, but it looks like you may be attempting to access the private state (the list) of one class (the ParticleController) from another class (The TutorialApp).

I'm assuming the following code structure (note that I haven't tried to compile this so it might not be quite right):

#include <list>

class ParticleController
{
    public:
        ParticleController() {}

        std::list<int> &getParticles2y() const
        {
            return mParticles2y;
        }

    private:
        std::list<int> mParticles2y;
}

class TutorialApp
{
public:
    void update()
    {
        // ...
        ParticleController mParticleController;
        //std::list<int> particles2y = mParticleController.mParticles2y; // error - accessing private member of another class
        std::list<int> &particles2y = mParticleController.getParticles2y(); // OK
    }
}
Ian Gilham
  • 1,916
  • 3
  • 20
  • 31
  • Wow thanks for that, it's almost completely the structure I have, the only thing is: in ParticleController everything is listed under public, nothing in private... But you are saying I should just make a function that returns the list, as that would be better? Sounds like a good solution __Edit: oh wait, I see you are actually just making the public list take over the private list, am I right? – laarsk Oct 26 '11 at 15:36
  • This is faulty, because it would allow a `const ParticleController` object to be modified, thereby invoking undefined behavior. `-1` from me. – sbi Oct 26 '11 at 15:42
  • @laarsk: And why couldn't you have posted such a simple piece of code, instead of wasting everybody's time? – sbi Oct 26 '11 at 15:43
  • Because I'm new to C++ and really do not understand everything you guys are talking about. I don't know how to begin solving problems in C++, I do not know how structures work in C++, I'm just trying to figure out this problem. It might be the wrong way to learn things the official way, but its kinda the only way I have now. I think. As for your comment: "it would allow a const ParticleController object to be modified", I honestly do not understand what you are talking about. That could be because I'm not english, or because I don't understand the principles of C++, I dont know. – laarsk Oct 26 '11 at 15:54
  • I really appreciate your help though. – laarsk Oct 26 '11 at 15:54
  • @sbi Thanks for pointing out that weakness. Obviously this code would need some const-ness enforced. It seems this has little to do with laarsk's problem after all, however. – Ian Gilham Oct 26 '11 at 16:12