After a bit of research I'm surprised to say I have not found a question like this anyway I'm just wondering why I can't assign a value to a static variable?
note I am not using any headers I'm just creating a class in one cpp file(I know not good practice) here is the error I get
main.cpp|17|error: ISO C++ forbids in-class initialization of non-const static member 'Rabbit::now'|
In Java this wouldn't be a problem
thanks
class Rabbit
{
public:
string name;
string color;
int age;
bool friendly;
int happiness;
static time_t now = 4;
const int currentID;
};
I'm just wondering why I can't assign a value to a static variable?
You most certainly can assign any value you'd like to a static variable. You just do not assign it within the class definition itself. The reason for this is that you cannot initialize a static variable more than once! If you were allowed to initialize it inside the class definition, that would be problematic.
I am not using any headers I'm just creating a class in one cpp file (I know not good practice)
Right. Well if you were using headers you'd see why static variable initialization inside the class definition would be problematic. Each translation unit where the header is included would be trying to initialize the static variable, which cannot happen hence the error you're seeing.
If you are asking how you would do this in c++, then
//.h
class Rabbit
{
public:
static int now;
};
//.cpp
int Rabbit::now = 4;
While observing another person's code, I realized that within class A's method he declared a local int with the same name as a variable of class A. For example:
classA.h:
class A{
int Data;
void MethodA();
};
classA.cpp:
#include "classA.h"
using namespace std;
void A::MethodA(){
int Data; //local variable has same name as class attribute
Data = 4;
//Rest of Code
}
I found it weird that the compiler would accept this without returning an error. In the above case, would the 4 be assigned to the local Data or A::Data, and what problems could this cause in more complex situations?
The local variable will shadow the member one (it has the more narrow scope). If you just write
Data = 4;
you will assign to the local variable Data. You can still access the member variable with
this->Data = 4;
This works basically just as
{
int data = 4;
{
int data = 2;
data++; // affects only the inner one
}
}
As for problems in the future: As long as you and everyone who will ever work with your code understands the rules and is aware that you did this on purpose there is no problem. If you do not intend to do such things on purpose, make your compiler warn about it.
However, it would certainly be saver if you followed a naming scheme for member variables, e.g. append an underscore like
class A{
int Data_;
void MethodA();
};
I have to call a static functions inside a class(say UserApp) which returns static value.
Class Definition and declaration done in 2 files.
File1.h:
userApp(){
static int* foo;
}
file1.cpp:
{
int* userApp::foo = 0;
...
.
.
foo = somevar;
}
The same class(userApp) is implemented in file2 and to avoid linkage error I'm forced to declare and define the static variable in file2 as well.
In file 2.cpp as userApp::foo is initialized to 0 , the return value of function getFoo is always zero.
I need the value associated to foo in file1.
Is there any way I can avoid defining static variable in file2?
Thanks in advance.
What a mess :D
If I understood you right, I believe you have to declare the static member as extern in one of the files, to indicate it's actually referencing to a variable declared elsewhere.
In UserApp.h:
class UserApp {
private:
static int* foo_;
public:
static int* getFoo() { return foo_; }
};
In UserApp.cpp:
#include "UserApp.h"
int* UserApp::foo_ = NULL;
In any other where you need to use it:
#include "UserApp.h"
...
int* foo = UserApp::getFoo();
You haven't provided any details about your namespace / class full of static things, but consider making more OO design or in case it seems reasonable to keep it in one class, consider implementing a singleton that would also allow you to hold the information about its state in more reasonable way. (you might end up with something like this)
I have noticed that some of my functions in a class are actually not accessing the object, so I made them static. Then the compiler told me that all variables they access must also be static – well, quite understandable so far. I have a bunch of string variables such as
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
and so on in the class. I have then made them all static const because they never change. However, my program only compiles if I move them out of the class: Otherwise, MSVC++2010 complains "Only static constant integral variables may be initialized within a class".
Well that's unfortunate. Is there a workaround? I would like to leave them inside the class they belong to.
They can't be initialised inside the class, but they can be initialised outside the class, in a source file:
// inside the class
class Thing {
static string RE_ANY;
static string RE_ANY_RELUCTANT;
};
// in the source file
string Thing::RE_ANY = "([^\\n]*)";
string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";
Update
I've just noticed the first line of your question - you don't want to make those functions static, you want to make them const. Making them static means that they are no longer associated with an object (so they can't access any non-static members), and making the data static means it will be shared with all objects of this type. This may well not be what you want. Making them const simply means that they can't modify any members, but can still access them.
Mike Seymour has given you the right answer, but to add...
C++ lets you declare and define in your class body only static const integral types, as the compiler tells. So you can actually do:
class Foo
{
static const int someInt = 1;
static const short someShort = 2;
// etc.
};
And you can't do that with any other type, in that cases you should define them in your .cpp file.
Some answers including even the accepted answer seem to be a little misleading.
You don't have to
Always assign a value to static objects when initializing because that's optional.
Create another .cpp file for initializing since it can be done in the same header file.
You can even initialize a static object in the same class scope just like a normal variable using the inline keyword.
Initialize with no values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str;
int A::x;
Initialize with values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str = "SO!";
int A::x = 900;
Initialize in the same class scope using the inline keyword
#include <string>
class A
{
static inline std::string str = "SO!";
static inline int x = 900;
};
Since C++11 it can be done inside a class with constexpr.
class stat {
public:
// init inside class
static constexpr double inlineStaticVar = 22;
};
The variable can now be accessed with:
stat::inlineStaticVar
Static member variables must be declared in the class and then defined outside of it!
There's no workaround, just put their actual definition in a source file.
From your description it smells like you're not using static variables the right way. If they never change you should use constant variable instead, but your description is too generic to say something more.
Static member variables always hold the same value for any instance of your class: if you change a static variable of one object, it will change also for all the other objects (and in fact you can also access them without an instance of the class - ie: an object).
I feel it is worth adding that a static variable is not the same as a constant variable.
using a constant variable in a class
struct Foo{
const int a;
Foo(int b) : a(b){}
}
and we would declare it like like so
fooA = new Foo(5);
fooB = new Foo(10);
// fooA.a = 5;
// fooB.a = 10;
For a static variable
struct Bar{
static int a;
Foo(int b){
a = b;
}
}
Bar::a = 0; // set value for a
which is used like so
barA = new Bar(5);
barB = new Bar(10);
// barA.a = 10;
// barB.a = 10;
// Bar::a = 10;
You see what happens here. The constant variable, which is instanced along with each instance of Foo, as Foo is instanced has a separate value for each instance of Foo, and it can't be changed by Foo at all.
Where as with Bar, their is only one value for Bar::a no matter how many instances of Bar are made. They all share this value, you can also access it with their being any instances of Bar. The static variable also abides rules for public/private, so you could make it that only instances of Bar can read the value of Bar::a;
Just to add on top of the other answers. In order to initialize a complex static member, you can do it as follows:
Declare your static member as usual.
// myClass.h
class myClass
{
static complexClass s_complex;
//...
};
Make a small function to initialize your class if it's not trivial to do so. This will be called just the one time the static member is initialized. (Note that the copy constructor of complexClass will be used, so it should be well defined).
//class.cpp
#include myClass.h
complexClass initFunction()
{
complexClass c;
c.add(...);
c.compute(...);
c.sort(...);
// Etc.
return c;
}
complexClass myClass::s_complex = initFunction();
If your goal is to initialize the static variable in your header file (instead of a *.cpp file, which you may want if you are sticking to a "header only" idiom), then you can work around the initialization problem by using a template. Templated static variables can be initialized in a header, without causing multiple symbols to be defined.
See here for an example:
Static member initialization in a class template
Optionally, move all your constants to .cpp file without declaration in .h file. Use anonymous namespace to make them invisible beyond the cpp module.
// MyClass.cpp
#include "MyClass.h"
// anonymous namespace
namespace
{
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
}
// member function (static or not)
bool MyClass::foo()
{
// logic that uses constants
return RE_ANY_RELUCTANT.size() > 0;
}
How do you create a static class in C++? I should be able to do something like:
cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
Assuming I created the BitParser class. What would the BitParser class definition look like?
If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example, then you won't be able to without using Managed C++.
But the looks of your sample, you just need to create a public static method on your BitParser object. Like so:
BitParser.h
class BitParser
{
public:
static bool getBitAt(int buffer, int bitIndex);
// ...lots of great stuff
private:
// Disallow creating an instance of this object
BitParser() {}
};
BitParser.cpp
bool BitParser::getBitAt(int buffer, int bitIndex)
{
bool isBitSet = false;
// .. determine if bit is set
return isBitSet;
}
You can use this code to call the method in the same way as your example code.
Consider Matt Price's solution.
In C++, a "static class" has no meaning. The nearest thing is a class with only static methods and members.
Using static methods will only limit you.
What you want is, expressed in C++ semantics, to put your function (for it is a function) in a namespace.
Edit 2011-11-11
There is no "static class" in C++. The nearest concept would be a class with only static methods. For example:
// header
class MyClass
{
public :
static void myMethod() ;
} ;
// source
void MyClass::myMethod()
{
// etc.
}
But you must remember that "static classes" are hacks in the Java-like kind of languages (e.g. C#) that are unable to have non-member functions, so they have instead to move them inside classes as static methods.
In C++, what you really want is a non-member function that you'll declare in a namespace:
// header
namespace MyNamespace
{
void myMethod() ;
}
// source
namespace MyNamespace
{
void myMethod()
{
// etc.
}
}
Why is that?
In C++, the namespace is more powerful than classes for the "Java static method" pattern, because:
static methods have access to the classes private symbols
private static methods are still visible (if inaccessible) to everyone, which breaches somewhat the encapsulation
static methods cannot be forward-declared
static methods cannot be overloaded by the class user without modifying the library header
there is nothing that can be done by a static method that can't be done better than a (possibly friend) non-member function in the same namespace
namespaces have their own semantics (they can be combined, they can be anonymous, etc.)
etc.
Conclusion: Do not copy/paste that Java/C#'s pattern in C++. In Java/C#, the pattern is mandatory. But in C++, it is bad style.
Edit 2010-06-10
There was an argument in favor to the static method because sometimes, one needs to use a static private member variable.
I disagree somewhat, as show below:
The "Static private member" solution
// HPP
class Foo
{
public :
void barA() ;
private :
void barB() ;
static std::string myGlobal ;
} ;
First, myGlobal is called myGlobal because it is still a global private variable. A look at the CPP source will clarify that:
// CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP
void Foo::barA()
{
// I can access Foo::myGlobal
}
void Foo::barB()
{
// I can access Foo::myGlobal, too
}
void barC()
{
// I CAN'T access Foo::myGlobal !!!
}
At first sight, the fact the free function barC can't access Foo::myGlobal seems a good thing from an encapsulation viewpoint... It's cool because someone looking at the HPP won't be able (unless resorting to sabotage) to access Foo::myGlobal.
But if you look at it closely, you'll find that it is a colossal mistake: Not only your private variable must still be declared in the HPP (and so, visible to all the world, despite being private), but you must declare in the same HPP all (as in ALL) functions that will be authorized to access it !!!
So using a private static member is like walking outside in the nude with the list of your lovers tattooed on your skin : No one is authorized to touch, but everyone is able to peek at. And the bonus: Everyone can have the names of those authorized to play with your privies.
private indeed...
:-D
The "Anonymous namespaces" solution
Anonymous namespaces will have the advantage of making things private really private.
First, the HPP header
// HPP
namespace Foo
{
void barA() ;
}
Just to be sure you remarked: There is no useless declaration of barB nor myGlobal. Which means that no one reading the header knows what's hidden behind barA.
Then, the CPP:
// CPP
namespace Foo
{
namespace
{
std::string myGlobal ;
void Foo::barB()
{
// I can access Foo::myGlobal
}
}
void barA()
{
// I can access myGlobal, too
}
}
void barC()
{
// I STILL CAN'T access myGlobal !!!
}
As you can see, like the so-called "static class" declaration, fooA and fooB are still able to access myGlobal. But no one else can. And no one else outside this CPP knows fooB and myGlobal even exist!
Unlike the "static class" walking on the nude with her address book tattooed on her skin the "anonymous" namespace is fully clothed, which seems quite better encapsulated AFAIK.
Does it really matter?
Unless the users of your code are saboteurs (I'll let you, as an exercise, find how one can access to the private part of a public class using a dirty behaviour-undefined hack...), what's private is private, even if it is visible in the private section of a class declared in a header.
Still, if you need to add another "private function" with access to the private member, you still must declare it to all the world by modifying the header, which is a paradox as far as I am concerned: If I change the implementation of my code (the CPP part), then the interface (the HPP part) should NOT change. Quoting Leonidas : "This is ENCAPSULATION!"
Edit 2014-09-20
When are classes static methods are actually better than namespaces with non-member functions?
When you need to group together functions and feed that group to a template:
namespace alpha
{
void foo() ;
void bar() ;
}
struct Beta
{
static void foo() ;
static void bar() ;
};
template <typename T>
struct Gamma
{
void foobar()
{
T::foo() ;
T::bar() ;
}
};
Gamma<alpha> ga ; // compilation error
Gamma<Beta> gb ; // ok
gb.foobar() ; // ok !!!
Because, if a class can be a template parameter, a namespaces cannot.
You can also create a free function in a namespace:
In BitParser.h
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex);
}
In BitParser.cpp
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex)
{
//get the bit :)
}
}
In general this would be the preferred way to write the code. When there's no need for an object don't use a class.
If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example
static classes are just the compiler hand-holding you and stopping you from writing any instance methods/variables.
If you just write a normal class without any instance methods/variables, it's the same thing, and this is what you'd do in C++
Can I write something like static class?
No, according to the C++11 N3337 standard draft Annex C 7.1.1:
Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions.
Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used
on type declarations. Example:
static struct S { // valid C, invalid in C++
int i;
};
Rationale: Storage class specifiers don’t have any meaning when associated with a type. In C ++, class
members can be declared with the static storage class specifier. Allowing storage class specifiers on type
declarations could render the code confusing for users.
And like struct, class is also a type declaration.
The same can be deduced by walking the syntax tree in Annex A.
It is interesting to note that static struct was legal in C, but had no effect: Why and when to use static structures in C programming?
In C++ you want to create a static function of a class (not a static class).
class BitParser {
public:
...
static ... getBitAt(...) {
}
};
You should then be able to call the function using BitParser::getBitAt() without instantiating an object which I presume is the desired result.
As it has been noted here, a better way of achieving this in C++ might be using namespaces. But since no one has mentioned the final keyword here, I'm posting what a direct equivalent of static class from C# would look like in C++11 or later:
class BitParser final
{
public:
BitParser() = delete;
static bool GetBitAt(int buffer, int pos);
};
bool BitParser::GetBitAt(int buffer, int pos)
{
// your code
}
You 'can' have a static class in C++, as mentioned before, a static class is one that does not have any objects of it instantiated it. In C++, this can be obtained by declaring the constructor/destructor as private. End result is the same.
In Managed C++, static class syntax is:-
public ref class BitParser abstract sealed
{
public:
static bool GetBitAt(...)
{
...
}
}
... better late than never...
Unlike other managed programming language, "static class" has NO meaning in C++. You can make use of static member function.
This is similar to C#'s way of doing it in C++
In C# file.cs you can have private var inside a public function.
When in another file you can use it by calling the namespace with the function as in:
MyNamespace.Function(blah);
Here's how to imp the same in C++:
SharedModule.h
class TheDataToBeHidden
{
public:
static int _var1;
static int _var2;
};
namespace SharedData
{
void SetError(const char *Message, const char *Title);
void DisplayError(void);
}
SharedModule.cpp
//Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;
//Implement the namespace
namespace SharedData
{
void SetError(const char *Message, const char *Title)
{
//blah using TheDataToBeHidden::_var1, etc
}
void DisplayError(void)
{
//blah
}
}
OtherFile.h
#include "SharedModule.h"
OtherFile.cpp
//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();
One (of the many) alternative, but the most (in my opinion) elegant (in comparison to using namespaces and private constructors to emulate the static behavior), way to achieve the "class that cannot be instantiated" behavior in C++ would be to declare a dummy pure virtual function with the private access modifier.
class Foo {
public:
static int someMethod(int someArg);
private:
virtual void __dummy() = 0;
};
If you are using C++11, you could go the extra mile to ensure that the class is not inherited (to purely emulate the behavior of a static class) by using the final specifier in the class declaration to restrict the other classes from inheriting it.
// C++11 ONLY
class Foo final {
public:
static int someMethod(int someArg);
private:
virtual void __dummy() = 0;
};
As silly and illogical as it may sound, C++11 allows the declaration of a "pure virtual function that cannot be overridden", which you can use alongside declaring the class final to purely and fully implement the static behavior as this results in the resultant class to not be inheritable and the dummy function to not be overridden in any way.
// C++11 ONLY
class Foo final {
public:
static int someMethod(int someArg);
private:
// Other private declarations
virtual void __dummy() = 0 final;
}; // Foo now exhibits all the properties of a static class
There is no such thing as a static class in C++. The closest approximation is a class that only contains static data members and static methods.
Static data members in a class are shared by all the class objects as there is only one copy of them in memory, regardless of the number of objects of the class.
A static method of a class can access all other static members ,static methods and methods outside the class
One case where namespaces may not be so useful for achieving "static classes" is when using these classes to achieve composition over inheritance. Namespaces cannot be friends of classes and so cannot access private members of a class.
class Class {
public:
void foo() { Static::bar(*this); }
private:
int member{0};
friend class Static;
};
class Static {
public:
template <typename T>
static void bar(T& t) {
t.member = 1;
}
};
class A final {
~A() = delete;
static bool your_func();
}
final means that a class cannot be inherited from.
delete for a destructor means that you can not create an instance of such a class.
This pattern is also know as an "util" class.
As many say the concept of static class doesn't exist in C++.
A canonical namespace that contains static functions preferred as a solution in this case.