Thread: The neccessity of classic programming in my case?

  1. #1
    Registered User MathFan's Avatar
    Join Date
    Apr 2002
    Posts
    190

    The neccessity of classic programming in my case?

    Hi!

    I am a programmer-hobbyist, who enjoys casual game programming and some slightly more useful programming for personal work. What I end up wondering every time I am writing some code is whether the amount of classes and protected members I use is appropriate. For example, this is one of the classes I usually have in my game projects:

    Code:
    //on a side notice: this class is further inherited by several other classes
    class GLObject
    {
        public:
            GLObject();
            ~GLObject();
            
            virtual void glRender() {}
            
            virtual void timeStep();
            
            Vector getPosition() const {return Position;}
            void setPosition(Vector NewPosition) { Position=NewPosition; }
            
            Vector getSize() const {return Size;}
            void setSize(Vector NewSize) { Size=NewSize; }
            
            Vector getVelocity() const {return Velocity;}
            void setVelocity(Vector NewVelocity) { Velocity=NewVelocity; }
            
            Vector getAcceleration() const {return Acceleration;}
            void setAcceleration(Vector NewAcceleration) { Acceleration=NewAcceleration; }
        
        protected:
            Vector Position, Size, Velocity, Acceleration;
    };
    The problem with this is that I have made all member variables protected. This prompts for two functions for each variable (a "set" and "get" function). What I really am worried about is that those functions (especially the "get" one) get called *really* often.

    Does this have any effect on speed or does it not? Would it be better to keep all of those members public, delete all the accessory functions and access variables directly? Or does this make the code more C-like? Is the latter necessarily a bad thing for C++ code? Am I so to speak overusing the classic programming approach?

    Any help and thoughts are highly appreciated!
    Thanks
    The OS requirements were Windows Vista Ultimate or better, so we used Linux.

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    The idea of using get()-and-set() member functions is considered good because it has multiple benefits:

    • First of all, it must be noted, that your class may not be the same in the future. You may wish to alter the internal representation of the data, or you may wish to provide a derived instance of the class to some other area of your program. All code relying on knowledge of the internal workings of this particular class will be broken if you ever render such assumptions invalid. This falls under the category of maintainability, as well as encapsulation.
    • Allowing unresticted access to variables of a class is generally not safe. The class itself should be responsible for knowing the full state of its variables at all times. If, for example, a class has a member variable that happens to be a pointer, it can take care to make sure such a pointer is never NULL from construction to desconstruction of each instance. If the user makes a mistake via a set() method and supplies a NULL pointer, the class can protect against bizarre output. While some would say such a scenario involving a pointer is unlikely, the general idea is still the same; the class is supposed to protect the integrity of the data. With public members, the data can be manipulated at any time from outside the class, but if the class is to be safe, it must evaluate the member variables for validity at every operation, thus not even being able to trust its own data.
    • In the same vein as the last point, this is easier on programmers to understand how such member data can be interacted with and altered simply by studying the member functions of a class. Otherwise, such study must be taken of the entire program to find out every possible way the data is being manipulated. Debugging can be more of a pain since the scope for errors is much larger. Thus, this point falls under the category of maintainability as well.


    In these days, get()-and-set() member functions do not take up that much space and time, and pay well enough for any delay by the safety that they provide. The speed difference should be negligable.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    With simple get functions, the compiler should inline them, killing any speed loss.
    There's also more advanced ways of getting rid of set/get while still keeping your members protected. I made a little wrapper that worked aka Visual Basic with get or = while still keeping members private.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User MathFan's Avatar
    Join Date
    Apr 2002
    Posts
    190
    Thank you for your informative replies, MacGyver and Elysia!

    Then I'll keep my current class structure. Is it though considered a good practice to declare these function as inlined explicitly, not necessarily for the compiler's sake (as it should do this by default, as you point out Elysia), but for the sake of code clarity?

    A further question on the issue, and I know this one probably is more of a personal preference, but really hope that some of you may have useful input for me here. When does one usually start using "typedef struct" instead of classes? For example in my current program I have a class called GLTexturePool in which I load, manage and store textures for my objects. Each texture is represented in my case by the following code:

    Code:
    typedef struct GLTexture
    {
        unsigned TextureID;
        string FileName;
        pngInfo TextureInfo;
    };
    
    class GLTexturePool
    {
    //...
    protected:
    vector<GLTexture> TexturePool;
    //...
    };
    As far as I can see, there is no need to convert GLTexture to a full-blown class with get and set-functions. What do you think?
    (GLTexture is not used anywhere outside the GLTexturePool class, it is just a conviniet storage unit reserved for this particular class. Retrieving information from the pool is done with help of public functions in GLTexturePool)
    Last edited by MathFan; 07-14-2008 at 02:52 AM. Reason: Ouch, now we do want to have a semicolon at the end of class definitions, don't we ;) now fixed in the code sample
    The OS requirements were Windows Vista Ultimate or better, so we used Linux.

  5. #5
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    I don't think you need the "typedef" aspect of it, but I have used the same technique of using a struct as a loose collection of variables often enough, although I have given some thought to trying to avoid it and convert such "packages of variables" into a real class.

    My reasons for consideration of such have largely been based on what language I'm using at the time. Java inherently makes sense to make all classes full blown classes. In a Java-like scripting-like language I was using, object creation is a heavy operation, and the language itself supports the idea of non-class structs, so such a technique can possibly be forgiven in that type of scenario.

    For C++ specifically, again, you don't need to write your code any specific way, but I imagine it would be beneficial to write it out as an actual class, especially if the data members are likely to change in any form. If you are fairly confident very few classes will deal with this struct, then you might be ok.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MathFan View Post
    Thank you for your informative replies, MacGyver and Elysia!

    Then I'll keep my current class structure. Is it though considered a good practice to declare these function as inlined explicitly, not necessarily for the compiler's sake (as it should do this by default, as you point out Elysia), but for the sake of code clarity?
    I would only mark it inline if it's not inside the class declaration. Most often, you would put the getter/setter directly inside the class, e.g.:
    Code:
    class X 
    {
       private:   // not needed, but there for clarity
         int x, y;
    
       public:
          int getX() { return x; }
          void setX(int ax) { x = ax; }
    };
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Typically, I don't ever write code inline in the definition unless they're one line or sometimes TWO maximum.
    For simple getters/setters, if your optimization is set to inline everything the compiler seems fit, it will inline all your getters/setters even if you don't specify inline.
    But it doesn't hurt to add the "inline" keyword anyway if you are not creating the function directly in the definition.

    As for the typedef keyword, it's not necessary. It's often used in C to get around having to type "struct mystruct" instead of "mystruct," but no such rule exists in C++.
    And if it were me, I'd make it a class and use emulated syntax to make it behave as a struct, because that would protect any changes I made later. That is, if I decided to evolve it as a class, I would not have to worry about rewriting the code if I changed it.

    But such an approach typically requires a good knowledge of templates. I wouldn't want to deter you to advanced topics until you feel it necessary. You could keep it as a struct, or make it a class and make the members public if you want. Or better yet, make them private and provide get/set, which would make it future-proof.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User MathFan's Avatar
    Join Date
    Apr 2002
    Posts
    190
    Thanks again for all your replies, that really clarified the issue
    The OS requirements were Windows Vista Ultimate or better, so we used Linux.

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    If your get and set functions are getting used a lot, this could indicate a bad smell in your code. Maybe whatever is calling get and set all the time should be refactored to be part of GLObject. Getters and setters provide minimal encapsulation at best.
    Last edited by medievalelks; 07-14-2008 at 06:07 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How can I make this code more elegant?
    By ejohns85 in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2009, 08:55 AM
  2. Format Precision & Scale
    By mattnewtoc in forum C Programming
    Replies: 1
    Last Post: 09-16-2008, 10:34 AM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Base converter libary
    By cdonlan in forum C++ Programming
    Replies: 22
    Last Post: 05-15-2005, 01:11 AM
  5. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM