Reputation: 484
Can anyone explain why we can call static member functions without creating instance of an object but we can't in case of non-static functions?
I searched everywhere, I couldn't find an explanation, Can you help?
Upvotes: 5
Views: 9680
Reputation: 17454
Because that's what static
means: "I don't want this function to require an object to work on".
That's the feature. That's its definition.
Any other answer would be circular.
Why is it useful? Sometimes we want to be able to "organise" some data or utilities in our classes, perhaps for use by external code or perhaps for use by non-static functions of the same class. In that sense there is some crossover with namespaces.
Upvotes: 0
Reputation: 31738
Why?
Because we like encapsulation and modularity which we get when using object orientated patterns.
You can view static
class member functions and variables as a way of encapsulating what would otherwise have been global functions and variables - which might collide.
Underneath, there is not a great deal of difference between a plain old C++ file with some functions declared and implemented in it, to a class filled with only static functions. The difference is we can cleanly access a set of functions attached to a parent class.
An example:
Suppose you want to create a new class like MyMediumInteger
, and you want developers to determine what the maximum number it can hold is. This information is applicable for every instance of MyMediumInteger
, no matter what the state of the private member variables are. Therefore it makes sense to expose this information without forcing the developer to instantiate the class. Your options include defining something global such as #define MYMEDIUMINTEGER_MAX ...
which could collide with a define sharing the same name in another module, or create a static
function returning the max size, called neatly via
MyMediumInteger::maxSize()
.
A code example:
/***
* Use a static class member function (or variable)
*/
class MyMediumInteger
{
public:
static unsigned long maxSize() { return pow(2, 32) - 1; };
};
auto maxSize = MyMediumInteger::maxSize();
/**
* Alternative approaches.
* Note: These could all collide with other #defines or symbols declared/implemented in other modules.
* Note: These are both independant sources of information related to a class - wouldn't it be nicer if they could just belong to the class instead?
*/
/***
* Use a #define
*/
#define MYMEDIUMINTEGER_MAX (pow(2, 32) - 1)
auto maxSize = MYMEDIUMINTEGER_MAX;
/**
* Use a global function or variable
*/
static unsigned long getMyMediumIntegerMaxSize()
{
return pow(2, 32) - 1;
}
auto maxSize = getMyMediumIntegerMaxSize();
A word of warning:
Static member variables and functions have some of the pitfalls of global variables - because they persist through instances of classes, calling and assigning to them can cause unexpected side effects (because static
member variables get changed for everyone, not just you).
A common pitfall is to add lots of static member functions and variables for management - for example, maintaining a list of all other class instances statically which gets appended to in the constructor of each class. Often this type of code could be refactored into a parent class whose job it is just to manage instances of the child class. The latter approach is far more testable and keeps things modular - for example, someone else could come along and write a different implementation of the management code without appending to or re-writing your child class implementation.
How?
In C++ class member functions are not actually stored in class instances, they are stored separately and called on instances of classes. Therefore, it's not hard to imagine how static functions fit into this - they are declared in the same way as normal class member functions, just with the static
keyword to say "I don't need to be given a class instance to be run on". The consequence of this is it can't access class member variables or methods.
Upvotes: 3
Reputation: 179819
You've got the logic basically in reverse. It is useful to have functions that belong to a class, even though they do not need to be called on an object of that class. Stroustrup didn't want to add a new keyword for that, so he repurposed the existing keyword static
to distinguish such methods from normal methods.
In hindsight, other options could have been chosen. We could have made this
an explicit function argument for the normal methods, for instance. But that's about 30 years too late now.
Upvotes: 7
Reputation: 135
Static member functions does not need a "this" pointer, it belongs to the class. Non-static functions need a "this" pointer to point out in which object it belong to, so you need to creat a object firstly.
Upvotes: 1