Static member functions
In the previous lesson on 11.13 -- Static member variables, you learned that static member variables are member variables that belong to the class rather than objects of the class. If the static member variables are public, we can access them directly using the class name and the scope resolution operator. But what if the static member variables are private? Consider the following example:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Something { private: static int s_value; }; int Something::s_value{ 1 }; // initializer, this is okay even though s_value is private since it's a definition int main() { // how do we access Something::s_value since it is private? } |
In this case, we can’t access Something::s_value directly from main(), because it is private. Normally we access private members through public member functions. While we could create a normal public member function to access s_value, we’d then need to instantiate an object of the class type to use the function! We can do better. It turns out that we can also make functions static.
Like static member variables, static member functions are not attached to any particular object. Here is the above example with a static member function accessor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Something { private: static int s_value; public: static int getValue() { return s_value; } // static member function }; int Something::s_value{ 1 }; // initializer int main() { std::cout << Something::getValue() << '\n'; } |
Because static member functions are not attached to a particular object, they can be called directly by using the class name and the scope resolution operator. Like static member variables, they can also be called through objects of the class type, though this is not recommended.
Static member functions have no *this pointer
Static member functions have two interesting quirks worth noting. First, because static member functions are not attached to an object, they have no this pointer! This makes sense when you think about it -- the this pointer always points to the object that the member function is working on. Static member functions do not work on an object, so the this pointer is not needed.
Second, static member functions can directly access other static members (variables or functions), but not non-static members. This is because non-static members must belong to a class object, and static member functions have no class object to work with!
Another example
Static member functions can also be defined outside of the class declaration. This works the same way as for normal member functions.
Here’s an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class IDGenerator { private: static int s_nextID; // Here's the declaration for a static member public: static int getNextID(); // Here's the declaration for a static function }; // Here's the definition of the static member outside the class. Note we don't use the static keyword here. // We'll start generating IDs at 1 int IDGenerator::s_nextID{ 1 }; // Here's the definition of the static function outside of the class. Note we don't use the static keyword here. int IDGenerator::getNextID() { return s_nextID++; } int main() { for (int count{ 0 }; count < 5; ++count) std::cout << "The next ID is: " << IDGenerator::getNextID() << '\n'; return 0; } |
This program prints:
The next ID is: 1 The next ID is: 2 The next ID is: 3 The next ID is: 4 The next ID is: 5
Note that because all the data and functions in this class are static, we don’t need to instantiate an object of the class to make use of its functionality! This class utilizes a static member variable to hold the value of the next ID to be assigned, and provides a static member function to return that ID and increment it.
A word of warning about classes with all static members
Be careful when writing classes with all static members. Although such “pure static classes” (also called “monostates”) can be useful, they also come with some potential downsides.
First, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it). For example, if you needed two independent IDGenerator objects, this would not be possible with a single pure static class.
Second, in the lesson on global variables, you learned that global variables are dangerous because any piece of code can change the value of the global variable and end up breaking another piece of seemingly unrelated code. The same holds true for pure static classes. Because all of the members belong to the class (instead of object of the class), and class declarations usually have global scope, a pure static class is essentially the equivalent of declaring functions and global variables in a globally accessible namespace, with all the requisite downsides that global variables have.
C++ does not support static constructors
If you can initialize normal member variables via a constructor, then by extension it makes sense that you should be able to initialize static member variables via a static constructor. And while some modern languages do support static constructors for precisely this purpose, C++ is unfortunately not one of them.
If your static variable can be directly initialized, no constructor is needed: you can initialize the static member variable at the point of definition (even if it is private). We do this in the IDGenerator example above. Here’s another example:
1 2 3 4 5 6 7 |
class MyClass { public: static std::vector<char> s_mychars; }; std::vector<char> MyClass::s_mychars{ 'a', 'e', 'i', 'o', 'u' }; // initialize static variable at point of definition |
If initializing your static member variable requires executing code (e.g. a loop), there are many different, somewhat obtuse ways of doing this. One way that works with all variables, static or not, is to use a lambda and call it immediately.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class MyClass { public: static std::vector<char> s_mychars; }; std::vector<char> MyClass::s_mychars{ []{ // The parameter list of lambdas without parameters can be omitted. // Inside the lambda we can declare another vector and use a loop. std::vector<char> v{}; for (char ch{ 'a' }; ch <= 'z'; ++ch) { v.push_back(ch); } return v; }() // Call the lambda right away }; |
The following code presents a method that behaves more like a regular constructor. However, it is a little tricky, and you’ll probably never need it, so feel free to skip the remainder of this section if you desire.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class MyClass { public: static std::vector<char> s_mychars; public: class init_static // we're defining a nested class named init_static { public: init_static() // the init constructor will initialize our static variable { for (char ch{ 'a' }; ch <= 'z'; ++ch) { s_mychars.push_back(ch); } } } ; private: static init_static s_initializer; // we'll use this static object to ensure the init_static constructor is called }; std::vector<char> MyClass::s_mychars{}; // define our static member variable MyClass::init_static MyClass::s_initializer{}; // define our static initializer, which will call the init_static constructor, which will initialize s_mychars |
When static member s_initializer is defined, the init_static() default constructor will be called (because s_initializer is of type init_static). We can use this constructor to initialize any static member variables. The nice thing about this solution is that all of the initialization code is kept hidden inside the original class with the static member.
Summary
Static member functions can be used to work with static member variables in the class. An object of the class is not required to call them.
Classes can be created with all static member variables and static functions. However, such classes are essentially the equivalent of declaring functions and global variables in a globally accessible namespace, and should generally be avoided unless you have a particularly good reason to use them.
![]() |
![]() |
![]() |
Hi ALEX,
How do we forward declare a class defined in other .cpp file in a project?
class className;
where className is the name of the class you're forward declaring.
Actually I Knew this, but this just gave me an error somewhere, So, I just wanted to confirm, But Now It's Fixed. Thanks Btw.
Hi Alex,
If normal member function can access the static variable, then why should I use static member function?
You'd use a static member function when you want to be able to access that static function, or static members, without instantiating an instance of the class.
Thanks Alex.
Hi Alex,
absolutely bloody loving the work you have put in here. Have been programming casually for a number of years and finally have gotten some clarity on the trickier concepts and reinforced the underlying reasons why things behave the way they do (and not jsut in c++, your tutorials have also shed light on many of the "quirks" I have encountered in other languages)
Other than heaping on general praise, appreciation and endless thanks:
L20 of third example should be std::cout
Glad you've found the tutorials useful. Thanks for pointing out the typo. Fixed!
Buy to mg pharmacy rx use how cialis http://mgpharmacyrx.com
Hi Alex, thanks for the great tutorial. I have a question: when I create a class with static member variable and static member function
"static int get_svalue() const { return s_value; }"
the compiler always reports an error when I set the function to const:
error C2272: 'get_svalue' : modifiers not allowed on static member functions
However, when I set it to non-consrt, it works just fine. Why is that?
Static member functions don't have a this pointer, so qualifying the function with const doesn't make any sense (since you can't modify the internal state of the class anyway).
I agree it would be nice to be able to create static member functions that guarantee to use static members in a read-only way, but C++ doesn't support that.
Hi Alex,
I have confusion regarding scope resolution operator.In the last example code of this article where you have defined our static object in global namespace.
Why you have used Myclass again after _init.Please explain how this is done?
_init is the type, but _init lives inside namespace MyClass, so it needs to be prefixed with MyClass.
s_initializer is the member's name. It also lives inside namespace MyClass, so it also needs to be prefixed with MyClass.
Without the MyClass before s_initializer, you'd be declaring a global variable of type MyClass::_init.
When you call any function of a class without object or argument than you have to use scope resolution operator to denote that function is calling from those particular class
When you call a function with argument than you can
simply call it
Hello Alex
i understood when could we use both the static members (variables and functions), but why would i use any of them outside the class instantiated objects eludes me , i mean why linking them to a particular class definition which has no objects yet when they could be defined as global's specially since the static function won't operate on any other variable that is none static ?
Static member variables are useful when you want all the objects of a class to share a single variable. Static functions are most useful when you want to be able to access a static member variable without having a class object, or when you want to associate a function that would otherwise be global with a particular class. In the latter case, this is really an organizational choice. In the former case, this can be used to do things like implement Singletons (when you want to ensure only one instance of a class can be instantiated).
Hi Alex,
I have a non technical question for you. When I look at other websites or forums I see people calling Member Functions as Methods.
Method is just a function inside of a class, correct? Do you not use this word because of personal preference or does member function != method..?
Thank you!
A method is the same thing as a member function. In C++, the term member function is normally used. Some other languages, like Java, use method instead.
In the last example, the name of the nested class begins with an underscore. Is this a style convention or is there some functionality to the underscore? I am working with an SDK for a device that has function names that begin with an underscore, for example _tmain(), and I am confused by it. Could you suggest where to find out more about this?
Sorry that my question is off topic. I have looked elsewhere and can't find an explanation. Thanks for the great tutorials.
There are many different reason people might use an underscore prefix. The most common case to use an underscore or double-underscore prefix is to denote that something is meant "for internal use" (by something else, even though the underscored name might be publically accessible). But some developers also use underscores to denote that a variable is private (e.g. a class's private member -- I prefer an m_ prefix in this case). In other cases, particularly for SDKs or libraries, it can be used as a way to avoid naming collisions if not using namespaces.
In this case, I opted for an underscore to help denote the the non-standard usage of the nested class.
Can u explain properties of static member function
Sorry, I am not sure what you mean. Can you clarify?
In your last sentence, I think you intended "globally namespace" to maybe read "globally accessible namespace".
Thanks, fixed!
Under "Static Member Functions", in the second paragraph, I think you may have meant to make "function" plural. You wrote:
"It turns out that we can also make function static."
First, the whole tutorial is really well written, even for dinosaurs like myself used to things like ticker tape and punched cards.
One little thing that I didn’t see, I checked a few times, that caught me out for a little while is that I tried writing a static function outside of the class definition without an internal definition (if that’s the correct terminology), as per :-
This produced error: ‘getNextAdultId’ is not a member of ‘Adult’.
I found that the commented out line in the above (static int getNextAdultId) was needed (i.e. uncommenting results in an OK compile and run). Perhaps, this requirement, if my conclusion is correct, could be added/clarified.
Me, being me, I saw this Note we don’t need to use the static keyword here. and therefore tried coding static. This, failed to compile, as per :-
ProjectsgettingStartedmain.cpp|59|error: cannot declare member function ‘static int Adult::getNextAdultId()’ to have static linkage [-fpermissive]
So it looks as though you cannot rather than need not code static, (perhaps it’s a c++14 or a compiler specific thing).
Again thanks for a great tutorial.
I updated the comments in the example to make it clearer that you still need the static declaration in the class.
To be clear, whether static or not, and whether a function or not, all members of a class have to be declared in the class declaration.
Newbe question here and just want to know how or what you can do to have a non-static class member variable accessed within a static function?
I am only doing some maintenance on someone else's code and therefore I do not want to change too much in the code, but I have a non-static member variable that I need to reference in this one function, but it is a static function and therefore I can not do it as it sits.
So if there are work arounds to get this to work then could someone know how to go about it???
The best way to do this would be to update the static function to accept a pointer or reference to a class object, and then access the member through the class parameter.
Hi alex
While initializing a static member variable outside the class, what is the need to specify the type again?
Isn't it already given within the class that s_nextID is int? Shouldn't it be enough to say IDGenerator::s_nextID = 1; while assigning the value? Why is it so?
Inside the class, a static member variable is essentially just a declaration. Outside the class, you need to define the variable, and variable definitions always include the type.
is std::cout a static class ?
I thought so because we only have one std::cout instance , a, I right ?
No, std::cout is a global variable of type std::ostream.
Hi,
what is use for "Static member functions",
what is different between "Static member functions" and "globa functions".
Thanks,
sameer
Static member functions are primarily useful for accessing static member variables.
There isn't much difference between a static member function and a global function, outside of the fact that the static member function is associated with your class whereas a global function isn't. This means static member functions can access the private static data members of the class, whereas global functions can't.
s_nNextID is private but we can access it directly outside the class declaration. I didn't understand this...can anyone explain me, please?
Static member variables are a little weird. There's only one instance shared across all instance of the class. For this reason, although the static member variable is declared inside the class, it is defined _outside_ of the class. For this reason, the initialization happens outside of the class too.
Note that because s_nNextID is private, you can't use it outside of the class -- this definition is purely for initialization purposes.
I think this is the only thing i have to memorize coz it is out of logic circle.
"There’s only one instance shared across all instance of the class." --- This not seems logical reason.
As per my understanding if it is private, it must not change valve out side of class whether its static or not, but here it is happening. Its strange.
Even this below defination also seems strange coz we have to again apply type int to the definition even though we declared type at the time of definition inside of class.
int IDGenerator::s_nNextID = 1;
The access specifiers only restricts whether a variable can be accessed directly from outside the class or not. A static member is treated just like a normal member in this regard. The fact that there is only one instance of a static variable shared across all member of the class is irrelevant to how it is accessed.
The static member variable is _declared_ inside the class, but it needs to be initialized outside of the class, at the point where it is _defined_. I agree that the way it is initialized is a little funny looking.
Hello Alex,
do I understand correctly?
Whether public or private, a static member variable can be defined anywhere because a static member definition is not subject to access controls i.e.
However, a private static member cannot be accessed directly outside a public static member function i.e.
Static members ARE subject to access controls, which is why you can't access a static variable or function from outside the class if it is declared private. However, you don't need an instantiated object to access them -- you can access them directly using the class name as a prefix.
Sorry, I am still confused.
In chapter 8.11 you have mentioned :
"Note that this static member definition is not subject to access controls: you can define and initialize the value even if it’s declared as private (or protected) in the class"
But here it is contradicting. Am I correct ?
No. For a static variable, the definition of the static variable outside the class is not subject to access controls (because you're not accessing it, you're defining it). However, use of the static member is subject to normal access controls.
hello everybody, i have a question.
in below code, why can i not be able to delete which previously i have been created instance? what’s wrong with my code?
thanks a lot.
Alex, Puppi's problem is mysterious to me too. Can you answer us..?
Thanks
You can't explicitly delete variable sn because it hasn't been dynamically allocated.
When sn goes out of scope, the destructor will naturally be called, which in this case will delete static variable inst, which is what you want anyway.
I removed that line + "pause"( may be it's a system call), put an output statement just after dynamically allocating memory like this:
and a strange thing happens. This line get printed again and again like an infinite loop. I moved that line from there to destructor before calling
getInstance (), the same thing happens, it goes infinite. Then I placed that line of code below the call to getInstance () in destructor. Nothing printed and program crashes. Why????
When sn goes out of scope, the destructor is called. The destructor calls Sample::getInstance(), which allocates an instance of Sample (which it really shouldn't be doing in a destructor, but lets put that aside) and then immediately deletes it (without setting inst back to null, so now inst is a dangling pointer). However, deleting it causes the destructor to be executed again. Since inst isn't null, it returns the dangling inst pointer, and tries to delete it again. This has undefined effects. In the best case, deleting it again will cause the destructor to be called again, re-deleting inst, causing the destructor to be called again, re-deleting inst, etc... An infinite loop.
In the worst case, it will crash.
In short, this program is extremely ill-formed. It's weird for a class to manage a static instance of itself. It leaves a dangling pointer after deleting the return value of getInstance(). And because inst is inside getInstance(), there's no way to set inst to null once it is deleted.
Thanks, confusion cleared
why static member function able to access private constructor
Please explane
class abc
{abc(){}
public:
static abc*instance;
staic abc* getinstance()
{
if(!instance)
instance = new abc();
return instance
]
abc *abc::instance =NULL;
};
Because the static function is a member of the class, just like a normal function.
<b>Hello alex,</b>
<p> Can you explain this to me? </p>
<p>Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it). For example, if you needed two independent IDGenerators, this would not be possible.</p>
With normal classes, you can instantiate as many objects of the class as you need. Assuming we had a class named IDGen that used normal (non-static) member variables to generate IDs, we could do this:
This would print "11".
The ID generators are independent.
Now consider similar code using the IDGenerator class that has all static members that we defined in the lesson above:
This would print "12", because one and two are sharing the same static member variables that generate the IDs.
I'm confused. Just before you describe the use of public static member functions to access private static member variables, you mention that "we can’t access Something::s_nValue directly from main(), because it is private." In the code snippets, however, on line 11 you initialize s_nValue to 1 directly. Why does this work? Shouldn't it fail since you are attempting to access a private member variable directly, even though it is static? Or does the limitation only apply inside a function, such as main()?
It works because s_value is a definition, and we're just providing an initializer. Because it's a definition, it's not subject to access controls.
class IDGenerator
{
private:
static int s_nNextID;
public:
static int GetNextID() { return s_nNextID++; }
};
// We'll start generating IDs at 1
int IDGenerator::s_nNextID = 1;
How is it possible to access s_NextID defined under private access specifier in the line above.
int IDGenerator::s_nNextID = 1; is a definition, and as such, it's not subject to access controls.
thanks a lot for sharing.
The whole of this example, with all of the static variables and methods, produces dangerous code. Threading becomes difficult (you have to build your own locks) and anybody can get to the variables from anywhere without the richness of the various c++ tools like boost, etc. This is completely done without problems, allowing the richness of the various other libraries that are aimed at OS management with a Singleton Pattern. I like the example (a href="http://www.yolinux.com/TUTORIALS/C++Singleton.html" title="here.">
Hello Alex,
Can you please explain me what is the use of making a constructor static and when we need to do that ?
hi, SUN, I think static constructor is used for :
1.initiating some static member variables of a class;
2.if you don't write the static constructor, and your class has some static member variables which already given the initial values, the compiler will automated generate a static constructor for you.
3. I think in database singleton design mode, it is useful. Because we don't want to generate too much accessing thread for the database, it is waste the resource.
thanks.
Hi leon,
Thanks a lot for the information
Regards!
C++ doesn't support static constructors. However, there are ways to work around that if you need to initialize static member variables in some complex way. I've updated the lesson to present one such method.
Hi Alex,
Did not understand the following....Can u explain?
"Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it). For example, if you needed two independent IDGenerators, this would not be possible."
What do u mean by two IDgenerators? Is it two classes?
Can some one explain the above paragraph in detail
Hi, Peter
“Second, because all static members are instantiated only once, there is no way to have multiple copies of a pure static class (without cloning the class and renaming it)."
Static Classes can only have one instance derived from them (not an object, but a call to the static class itself.). Non-static classes can have an infinite number of instance derived from them (objects). Consider the example below; it's an excerpt from a small Console app I wrote in Visual C++ Studio Express 2010:
"... if you needed two independent IDGenerators, this would not be possible."
You can only derive one instance from a static class, and it is not an object.
I Hope this helps ...
4lgor1thm
Thanks 4lgor1thm...:)
//cStaticClass::getValue(); //Throws an exception, cannot access static methods and variables of an instantiated object of a static class
this error i am not getting
cStaticClass.getvalue();----> i have written iike this i am not getting any error
cStaticClass is a object right so we can access member function or data of the claa by dot operator right.
y can u explain me in detail why i am not getting error
Seems STATIC classes are not supported under C++ ... ??
When I tried to compile the above code I get error saying
"error: a storage class can only be specified for objects and functions"
Yes, the static keyword can not be applied directly to a class. However, a class with all static member variables and static member functions is essentially a static class.
Absolutely short and sweet !
The examples are simply simple to understand the concept...Thanks a lot
Very good explanation and examples..
Grate explaination with accurate examples