SilverBackApe
SilverBackApe

Reputation: 247

C++ Global Variable vs Java instance variable

I have a question about global variables in C++. I'm coming from a Java background where you can have an instance variable declared and used like so:

Example.java

class Example
{
   int x;

   doSomththing()
   {
      x = 1;
   }

   doSomethingElse()
   {
      x = 2;
   }
}

My question is, in C++ if i do something similar, would that be classified as a global variable or an instance variable. Observe my C++ example to clarify:

Example.h

class Example{

public:
void do_something();
void do_somethingElse();

private:
int x;

};

Example.cpp

#include Example.h

void Example::do_something()
{
    x = 1;
}

void Example::do_somethingElse()
{
    x = 2;
}

So in the C++ example, is x a global or an instance variable? If its not a global, then how can x be properly defined as a global?

Upvotes: 0

Views: 1547

Answers (4)

Christian Hackl
Christian Hackl

Reputation: 27518

First of all, you should know that your Java example cannot be translated 1:1 to C++ because C++ doesn't know package-private accessibility (in fact, C++ doesn't really have packages at the language level, and a proposal to add them to the language didn't make it into C++11). Your class Example as well as its x field and methods are package-private, which means that they are hidden from any code outside of the package.

C++ only knows public, protected and private, which largely (but not fully!) correspond to their Java equivalents, but it also knows friend functions and classes, which can sometimes be used to achieve results similar to package-private accessibility.

Apart from this accessibility issue, the x variable in your C++ example is the same as in your Java example, i.e. it is an instance variable, with separate values in every instance of the class.

Global variables are possible in C++, but as you may already know, they are usually bad design. Imagine this complete C++ program:

int x; // global variable, usually bad

int main()
{
  x = 123;
}

Does this mean that Java prevents such bad design, however? No, it does not. It shields you from some surprising dangerous low-level aspects which come with global variables in C++ (read more about the static initialization order fiasco for details), but not from the bad high-level aspects. A public static variable which is not final is much like an ordinary global variable in C++.

Take this Java code, for example:

public class Example {
    public static int x; // hardly better than a global variable in C++
}

This is hardly better than a "real" global variable in C++. Every piece of code in your whole program can access it, which increases tight coupling and affects testability.

Here's another example for a bad global variable in disguise in Java:

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private int x; // global variable in disguise

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }

    public int getX() {
        return x;
    }

    public void setX(int newX) {
        x = newX;
    }
}

(Yes, the Singleton design pattern is nothing more than a glorified global variable in 99% of all cases I've ever seen in any piece of code.)

The point is: technically Java doesn't feature global variables like C++, but it's not hard to emulate their behaviour and defects, and then they are exactly as bad (minus some low-level initialization issues present in C++). They just look nicer and "cleaner" with all the class stuff around them, especially to beginners.

By the way, you can implement the Singleton (anti) pattern in C++ as well, and it is typically not much more than a glorified global variable there as well:

class Singleton
{
private:
    static Singleton *instance;
    int x; // global variable in disguise
    Singleton() : x(0) {}
public:
    static Singleton &instance()
    {
        // ignoring any concurrency issues for
        // simplicity's sake, don't try this at
        // home

        if (instance == nullptr)
        {
            instance = new Singleton;
        }
        return *instance;
    }

    void setX(int newX) { x = newX; }
    int getX() const { return x; }
};

You can also create a simpler global variable in disguise with the combination of static, public and non-const, just like in Java:

class Example
{
public:
    static int x; // global variable in disguise
};

Just to make this very clear: static is not evil. But you have to know where to apply it, and you have to realise that the combination of public, static and non-final/non-const is usually a (well-intended, but short-sighted) replacement for "real" global variables, in Java as well as in C++.

Upvotes: 0

Jeff
Jeff

Reputation: 2495

Just like in Java or C#, x is also an instance variable. For better or for worse, C++ allows variables outside of a class definition, such as follows:

class Example{

public:
    void do_something();
    void do_somethingElse();

private:
    int x;
};

Example.cpp

#include Example.h

static int g_value = 17;
extern int g_another_value;

void Example::do_something()
{
    x = g_value + g_another_value + 1;
}

void Example::do_somethingElse()
{
    x = g_value - g_another_value + 2;
}

OtherCode.cpp

int g_another_value = 31;
// other code

In this case, the static keyword will allow the scope to only this file, however removing static, and re-declaring the variable in other cpp files preceeded by the keyword extern will allow the compiler to be happy and the linker will resolve the variable.

Hope this helps.

Upvotes: 1

T-Bull
T-Bull

Reputation: 2146

A global variable is declared in C/C++ by just putting it at the top level, outside any class statement, something which is not possible in Java.

int y;

The variable x in your example is clearly an instance variable. Apart from the visibility (private vs. package) it is exactly equivalent to x in your Java example.

Upvotes: 1

Karalix
Karalix

Reputation: 141

As x is not the same if you create a new instance of Example, it is a instance variable. If you want x to be shared between all instances of Example, you should define it as static

Upvotes: 3

Related Questions