JavaRunner
JavaRunner

Reputation: 2545

C++: Global variable vs local variables. What to use?

Sometimes I wanna use globals but instead of it I use local variables. Let we have some Font class:

class Font {
public:

    class Alignment {
    public:
        unsigned short currentAlignment;
        unsigned short FONT_ALIGN_LEFT = 0;
        unsigned short FONT_ALIGN_CENTER = 1;
        unsigned short FONT_ALIGN_RIGHT = 2;
        // etc....
    };

    Alignment alignment;

    void setFontAlignment( unsigned short fontAlignment ) {
        this->alignment.currentAlignment = fontAlignment;
    }

};

To use this class we need to do something like that:

Font font;
font.setFontAlignment( font.alignment.FONT_ALIGN_CENTER );
// if we need to check currentAlignment we need to do:
if ( font.alignment.currentAlignment == font.alignment.FONT_ALIGN_CENTER ) {...} // looks a little bit awful :)

Or we have another approach to do this:

= Font.h =
#define FONT_ALIGN_LEFT 0
#define FONT_ALIGN_CENTER 1
#define FONT_ALIGN_RIGHT 2 
// etc....

class Font {
public:
    unsigned short currentAlignment;
    void setFontAlignment( unsigned short fontAlignment ) {
        this->currentAlignment = fontAlignment;
    }
}

To use this:

#include "Font.h"
...
Font font;
font.setFontAlignment( FONT_ALIGN_CENTER );
if ( font.currentAlignment == FONT_ALIGN_CENTER ) {...} // looks a little bit better :)

Which one is better for memory optimizing and why? Which one do you prefer to use? Or maybe you know some better solutions?

Upvotes: 0

Views: 731

Answers (2)

Paul92
Paul92

Reputation: 9062

Actually, a combination of them. But let's clarify something. You don't speak about any global variable in your question. A global variable is a variable defined in the global scope.

The primary reason of using object oriented programming is not its efficiency (as it is slower than purely procedural code), but its ability to model the world. So, when creating an oop design, you shouldn't care too much about the resourced (time, memory), but how good it models the world.

The second version is bad, because it introduces a lot of constants in the global scope, and you want to avoid that. Also, it does a very bad job at encapsulating the data (the user of your Font class shouldn't care about the values of the alignment).

The first version is better, but there are some problems. First, you need to think about the objects you should have? Do you actually need an Alignment object? You may need it, but in this particular example, I don't see why. So, you could make it model the world as it is, without introducing some artificial elements:

class Font {
public:

    unsigned short currentAlignment;
    void alignLeft() {
        this->currentAlignment = 0;
    }
    void alignCenter() {
        this->currentAlignment = 1;
    }
    void alignRight() {
        this->currentAlignment = 2;
    }  
};

Now it is very easy to use. I don't have to keep in my global scope unnecessary constants. Now, the problem is what happens when the user reads the value of the currentAlignment? Of course, you don't want to use the constants, but you don't need to. It really depends on the world you're modelling. As this is a Font class, it should be the only one who really cares about the value of the alignment. If somebody else needs the value, you could have some methods like isCenter() that return true when the font is center-aligned. But also, I would consider making the currentAlignment private.

Upvotes: 1

David Elson
David Elson

Reputation: 221

Although there are always exceptions, I usually go by (among others :-) the following guidelines:

  • Avoid globals as much as possible. Confine to smallest applicable scope (within reason).

  • Avoid second guessing the compiler, except for grossly obvious situations.

Upvotes: 1

Related Questions