Reputation: 247
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
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
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
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
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