Thread: May God strike down pointers

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    71

    May God strike down pointers

    Hey all,

    I have a problem with pointers, one which I am completely unable to comprehend. But first, here's part of the code:

    Code:
    /* The controling class of the whole program. Calls the functions responsible for displacement calculation and object rendering,
     * as well as containing a pointer to the first object in the linked list
     */
    
    #ifndef CLASS_UNIVERSE_H
        #define CLASS_UNIVERSE_H
    
    #include "ClassStar.h"
    #include "ClassValues.h"
    #include "ClassMath.h"
    #include "ClassGravCalc.h"
    #include "ClassRender.h"
    #include "ClassPosRegulator.h"
    
    
    class ClUniverse {
        private:
    
        ClStar* m_STARS;
    
        public:
    
        ClUniverse();
    
        void calculateDisplacement();
        void drawObjects();
    };
    
    #endif
    Code:
    #include "ClassUniverse.h"
    #include <iostream>
    
    using namespace std;
    
    ClUniverse::ClUniverse()
    {
        m_STARS = new ClStar(ClValues::nNumObjects);
    }
    
    void ClUniverse::calculateDisplacement()
    {
        ClStar* curStar = m_STARS;
        ClStar* nxtStar;
        for(int x = 0; x < ClValues::nNumObjects; x++, curStar = curStar->getNextNode()) {
            nxtStar = curStar->getNextNode();
            while(nxtStar != 0) {
                ClGravCalc(*curStar, *nxtStar);
                ClPosRegulator(*curStar);
                cout << curStar << endl;
                cout << (curStar->getPosition()).getX() << endl;
                cout << (curStar->getPosition()).getY() << endl;
                cout << endl;
                nxtStar = nxtStar->getNextNode();
            }
        }
    }
    
    //The change of color of the star from center out is given by the function in ClMath, as well as the increase of its transparency
    void ClUniverse::drawObjects()
    {
        clear(ClValues::dblbuffer);
    
        ClStar* curStar = m_STARS;
    
        drawing_mode(DRAW_MODE_TRANS, 0, 0, 0);
    
        for(int x = 0; x < ClValues::nNumObjects; x++, curStar = curStar->getNextNode())
            ClRender(ClValues::dblbuffer, curStar->getPosition(), curStar->getRadius());
    
        vsync();
        blit(ClValues::dblbuffer, screen, 0, 0, 0, 0, ClValues::nScreenHight, ClValues::nScreenWidth);
    }
    Code:
    /* This class will wrap around the position of an object if necessary
     */
    
    #ifndef CLASS_POS_REGULATOR_H
        #define CLASS_POS_REGULATOR_H
    
    #include "ClassStar.h"
    #include "ClassVector.h"
    #include "ClassValues.h"
    
    struct ClPosRegulator {
        ClPosRegulator(ClStar& Star);
    };
    
    #endif
    Code:
    #include "ClassPosRegulator.h"
    
    ClPosRegulator::ClPosRegulator(ClStar& Star)
    {
        //Move the object so that the upper left part of the Universe corresponds to [0, 0]
        long int nInvisiblePartHight = (ClValues::dUniverseSize - 1) * ClValues::nScreenHight / 2;
        long int nInvisiblePartWidth = (ClValues::dUniverseSize - 1) * ClValues::nScreenWidth / 2;
        ClVector vecScreen(ClValues::nScreenWidth, ClValues::nScreenHight);
        ClVector vecInvisiblePart(nInvisiblePartWidth, nInvisiblePartHight);
        ClVector vecNewPosition = Star.getPosition() + vecInvisiblePart;
    
        //Wrap position of object if necessary
    
        Star.setPosition(vecNewPosition % (ClValues::dUniverseSize * vecScreen) - vecInvisiblePart);
    }
    I'm attempting to make a simulation of star movement. It works fine, I've long since compiled it. I've been adding and tweaking ever since, and I wanted to add a class (ClPosRegulator) that would wrap the position of the star should it go off the screen. I have a class ClStar which is set up to work as a linked list (as in I have a linked list of ClStars), where m_STARS points to the first node. So what I do in the code above is loop through the "stars", calculate the displacement due to gravity using the function ClGravCalc (already been in use for some time, no problems there) and then attempt to wrap around the position of the stars using ClPosRegulator. Unfortunately, if I try to compile the above code without the cout's, it gives me a warining "unused variable curStar" on the line where I call ClPosRegulator (which is evidently nonsense as I use it before) and the "stars" don't wrap around. If I compile with the cout's, it gives me

    error: 'struct ClPosRegulator' has no member named 'getPosition'
    error: 'struct ClPosRegulator' has no member named 'getPosition'

    If I comment out the problematic cout's (the ones containing calls to getPosition()), it compiles fine, and the remaining cout outputs only zeros. If I place the cout's before the call to ClPosRegulator, it compiles fine and they output the expected values (two values representing XY coordinates, and an address in hexadecimal), so the problem has to be somewhere in ClPosRegulator.

    I know I didn't explain the logic behind 90% of the code, because I'm hoping that the error is something one of you can spot without knowing what the purpose of the code is. If you need any additional info, feel compelled to ask for it in a reply.

    Cheers,

    Gabe

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    ClPosRegulator(*curStar);
    Preliminary tests seem to indicate that this line is being treated as a (re)declaration of the variable curStar rather than calling the constructor of the class clPosRegulator.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You misuse constructors as functions. Why?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    Registered User
    Join Date
    Mar 2008
    Posts
    71
    Preference, I guess. Is there any disadvantage?

    And that fact that the compiler considers it a redeclaration (it's already declared a few lines above) baffles me as much as the consequences. Any tips?

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    hmm... looks like you have run into a problem similiar to this:
    Code:
    int(n);
    where it is equivalent to:
    Code:
    int n;
    When faced with the former line of code (on this forum, I think), I assumed a compile error since n was not declared at that point, but it turned out that the statement itself was a declaration of n.

    For your case, a possible solution is to force it to be interpreted as a constructor invocation by casting to void:
    Code:
    static_cast<void>(ClPosRegulator(*curStar));
    but there might be a better solution (besides just turning it into a function or "normal" function object).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I guess you can also give a name to the instance:

    Code:
    ClPosRegulator dummy(*curStar);
    I don't get this preference, though. A class that exists only because its constructor has a side-effect doesn't seem very OOP, and creates syntactic difficulties like this. Why?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Registered User
    Join Date
    Mar 2008
    Posts
    71
    Well it seem very OOP to me. You need something done, and to get that something done, you have to build something else. So you build the something else, run the original something through it, and then since you're finished, destroy the something else. That might be a little confusing, so here's a pretty stupid example: I need a photo with a sand castle in it. So I build the castle, take the picture, and then, since I don't need the castle anymore, destroy the castle. Personal preference comes in because it also looks stylish in my opinion.

    But you have a point with the syntactical difficulties (in my previous post I didn't know this was the cause), and I'm thinking of reimplementing the whole thing using the parenthesis operator, making an instance, and then just using that. Anyhow, thanks for the feedback everyone, you've been a great help. I'll give a shout if anything goes wrong.

    Cheers,

    Gabe

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You can also think about it this way. You use a free function instead of a contructor call. The code looks exactly as you wanted, except now it works.

    What is different in the big picture? Nothing. How come the same code with practically identical layout is OOP in one case and not OOP in the other?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    "You need something done, and to get that something done, you have to build something else."

    O_o

    How do you build "something else"? Isn't "building something" "getting something done"? If that doesn't point out some flaw... recurse.

    Soma

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well it seem very OOP to me.
    It isn't. Objects for the sake of objects are OOW, not OOP, and I can't tell you what the W stands for on a family-friendly forum.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Mar 2008
    Posts
    71
    Hey, all right already :-D I get the message. I'll be a good boy from now on. Is converting it to a function object the right thing to do?

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    How about a plain function? Why are you afraid of free functions?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If the function object doesn't need any state, and you are not going to use it as a predicate (failing to use standard C++ libraries - e.g std::list or any other container instead of reinventing the linked list - is another issue with the code), why would having an object be important.

    Code:
    //why write
    do_something()(x, y);
    
    //instead of a simple function call
    do_something(x, y);
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  14. #14
    Registered User
    Join Date
    Mar 2008
    Posts
    71
    As I said, that part is preference; I just prefer not to have functions declared basically in the middle of nowhere. I always prefer to have an object containing the function I need, even if that means declaring a completely new object.

    And I never needed to use the STL libraries, since I've never done anything that would need all the stuff they offer, plus I like to do everything on my own. It's a style of learning and practicing I've developed; otherwise, I could have easily downloaded half the classes I use off the internet, and it would probably be more efficient. But as I still consider myself in the process of learning (this is my first larger program in C++) I think it's better if I do everything myself for now. Anyone can learn to use what someone else has made. I like to make the stuff as well. Also, using classes someone else made takes a great deal of fun out of the project, and that is the main reason I'm doing this at all.

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    But as I still consider myself in the process of learning (this is my first larger program in C++) I think it's better if I do everything myself for now.
    I disagree. If you want to know how a linked list works, by all means write one yourself. But learning the standard library of a language is as important as learning the language itself, so you should use it in non-trivial programs.

    As I said, that part is preference; I just prefer not to have functions declared basically in the middle of nowhere.
    You're thinking like a Java programmer. C++ is a multi-paradigm language. You're supposed to pick the best from every paradigm. And having stuff that is independent of an object being done by a free function is the right thing to do.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. array of pointers to an array pointers
    By onebrother in forum C Programming
    Replies: 2
    Last Post: 07-28-2008, 11:45 AM
  2. Hey guys..need help on pointers
    By Darkozuma in forum C++ Programming
    Replies: 5
    Last Post: 07-25-2008, 02:57 PM
  3. Using pointers to pointers
    By steve1_rm in forum C Programming
    Replies: 18
    Last Post: 05-29-2008, 05:59 AM
  4. GOD and religion
    By Unregistered in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 10-14-2001, 05:13 PM
  5. Foundations
    By mithrandir in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 10-05-2001, 02:18 PM