This question already has answers here:
Static vs. member variable
(4 answers)
Closed 8 years ago.
Is it a good practice to use a static variable inside member function instead of member variable for a variable that should preserve its value between function calls?
Consider the following example: I have a class with an update() function where some 3D object is being rotated every frame. I sometimes see the following code:
void Class::update(float frameTime)
{
static float rotation = 0.0f;
rotation + = m_rotationSpeed * frameTime
if (rotation >= 360.0f) rotation -= 360.0f;
// ...
}
This can just as well be implemented using a member variable.
Are there any reasons to prefer one implementation over the other? It seems to me like using a static like this does improve encapsulation and also results in a smaller object, but on the other hand it seems somewhat less intuitive.
Please note that a class like that is usually meant to be used in single instance, and, since C++11, static variable should be thread safe.
It makes very little sense to use a static variable here, because all instances of Class will access the same variable. It is very unlikely that you need to share rotation between instances like this.
If you want to restrict a class to being a single instance, then you have to make sure it can only be instantiated once. But this is usually a sign that a re-design is in order.
I would say if you use singleton approach it's meaningless using static field. Even if your project won't get any bigger.
Do not go with static typically. Static means you can use it without declaring an object. Static doesn't fit your case. Just because there's only one of it doesn't mean it needs to be static.
Static is useful usually when you have something perhaps you want to be able to compare to without two instances of the object.
I.e perhaps you have a shape object, and it has an enum for color. By making the enum static, you can do something such as if(myShape.shapeColor == Shape::color::red) Usually however, I stay away from static. It's one of those things that has its uses and doesn't need to be broadened any further.
Edit:
Actually, making the enum static in that case won't change anything. I guess I'll to try to keep my answer somewhat valid, and so I'll pretend that you could not use enums in this case. (Even though this is a c++ question, I'm just getting a point across). You could declare say, a series of constant static integers. You would not be forced to have two objects for comparisons.
Using static like this is ok for a small application however as the application grows larger there then becomes the issue of using static where you would want to use a member variable due to the scalability of it over using static.
There is no 'good pratice' here as they don't do the same thing :
A member variable (attribute) will be updated only by the current instance of the class.
A static variable will be modified by all the instances of that class.
For example the class
class Foo
{
void bar()
{
static int bar = 0;
std::cout << bar << std::endl;
bar++;
}
};
given this main
int main()
{
Foo one, two;
one.bar();
two.bar();
two.bar();
one.bar();
}
will output
1
2
3
4
Related
AFAIK In C++, we call the getter/setter function as 'property'.
The getter/setter is used to get/set a member variable.
One of the advantages of doing this is that we can listen for change, like this:
// In header:
class XXX {
int m_width{};
void OnWidthChanged() {
// do something...
}
public:
int Width() const {
return m_width;
}
void Width(int val)
m_width = val;
this->OnWidthChanged();
}
};
// In CPP:
XXX my_xxx;
my_xxx.Width(123);
cout << my_xxx.Width() << endl;
Now I found static variable can be used to implement similar thing, in a non-OOP fashion I know it cannot handle multiple-instance, so let's just assume XXX is an object that has only 1 instance.
// In header:
int XXX_Width(bool set = false, int val = 0);
void XXX_OnWidthChanged();
// In CPP:
int XXX_Width(bool set, int val) {
static int width = 0;
if (set) {
width = val;
XXX_OnWidthChanged();
}
return width;
}
XXX_Width(true, 123);
cout << XXX_Width() << endl;
My question is, is there a name or term for this kind of functions functions like XXX_Width()?
I'm looking for a name so I can google search for related information.
I'm not asking for name for OnWidthChanged().
Lots of confusion about terminology here.
OOP simply means that you have autonomous classes with their functionality encapsulated. Both your examples use OO, though if they are bad or good design is another matter.
Now I found static variable can be used to implement similar thing, in a non-OOP fashion:
There is nothing non-OOP with your example. It is however probably bad OO design, since multiple instances of your class may access that same function. It is also bad design from a thread-safety perspective.
Sometimes, using static variables locally is perfectly fine though, like for example when implementing "singleton" classes.
In C++, we call the getter/setter function as 'property'
No, that is not a common term. Getter/setter functions are called members, or member functions. Or possibly public member functions, since by definition those must be public. Another term used for them is methods.
The term property is most often used to describe public member variables. Often RAD tools use the term property for such variables.
My question is, is there a name or term for this kind of functions?
A function which is specified by the caller, but called by someone else (the class, the OS, an interrupt etc) is universally called callback function. This is a fairly broad term.
In your case, you seem to use callback functions like "events" - an event is a kind of callback function but a higher level concept. Code like your example could be used for so-called "event-driven design", which is also popular among RAD tools.
The 1st point that should be made is that your "property block" or "getter/setter" are non-conformant. The expected declarations look like:
int Width() const;
void Width(const int);
So when you change the setter to: XXX& Width(int) it becomes clear that you aren't talking about "property blocks" or "getter/setters". So let's talk about what your setter does look like:
It makes a call after width changes. Such a call would typically be an interupt or a signal
It returns a non-const reference to the object. This is the behavior of an operator which notably do have outside class versions
Now let's talk about your function: int XXX_Width(bool set = false, int val = 0) You've set it up with default arguments such that it could behave as either the setter or the getter in your example, notwithstanding the weirdness of your getter's return.
Given the distinction between the 2 options you present, you seem to be asking:
Is there a name for using a functions static variable instead of defining a function and providing getter/setters for a member variable?
A function scoped static variable is called a static local variable.
One word of wisdom on static local variables:
A static local variable is different from a local variable as a static local variable is initialized only once no matter how many times the function in which it resides is called and its value is retained and accessible through many calls to the function in which it is declared [source]
Instead of making a new question I will edit this one by completely erasing the previous one, hopefully making it less confusing.
Wall of text.
I have a basic struct that has some basic values, such as image width, height and x and y positions, like so:
struct obj {
int id = 0;
float x = 0;
float y = 0;
int image_w = 0;
int image_h = 0;
int depth = 0;
}
I then have an initialiser function that creates the members of that struct and stores them in an array. If that array is named "instance" then individual members and their values can be accessed by simply doing this: instance[number].x etc..
Then I have a loop or two which handle all these members and do so in the order of their depth value, defined in struct and set in initialiser function. Like so (simplified):
for (i=0;i<maxdepth;i++) {
if (instance[n].depth == i) { doStuff; }
}
In "doStuff" function I check the members' id value in a switch statement and then have them do whatever I want inside case labels; this gives me the option to have some individual behavior within the same struct. And here is where the problem is. Although this works just fine I can't have individual fixed (or starting) variables within certain members without every member having those same variables and obviously with enough members this eventually results in a struct that is simply undesirably big and has a lot of redundancy; wasted resources. E.g I want some members to have speed and direction variables but don't want to give them to static members of the same struct that don't need them.
The question is, how do I achieve this effect without changing the fundamental idea of using structs or is there a better alternative to do this?
And I'm sorry about formatting and all; this is my first question on this website.
My understanding of structs is that the bigger it is the more time it takes to access its individual variables.
Your understanding is fundamentally mistaken. The size of a struct has little (if any) effect on the time required to access an individual variable inside that struct.
Regardless of that, however, your basic idea of structuring the data so one struct contains (or owns a pointer to) some other structs is perfectly fine and reasonable.
What's not so fine or reasonable is making that pointer essentially un-typed so it can refer to any other type. If you want a collection of clothes, you'd probably start with a clothing base class, and then derive various other types from that (coat, shirt, slacks, jeans, etc.). Then the person type might contain (for example) a vector of pointers to clothing, so it can contain pointers to all the other types derived from clothing.
As far as "extending scope" goes...well, I can't say much beyond the fact that I can't make much sense of what you're trying to say there.
The const member function guarantees that no member variables can be changed by the member function unless they are marked as mutable.
That being said it guarantees nothing else?
Here is a real example. I have a classes EventHandler and EventDispatcher.
class EventHandler
{
public:
void registerHandler(EventHandler* handler) const // Should this be a const?
{
EventDispatcher::registerHandler(handler);
}
};
EventDispatcher // Singleton Class
{
public:
void registerHandler(EventHandler* handler)
{
mListeners.push_back(handler);
}
private:
std::vector<EventHandler*> mListeners;
};
Should EventDispatcher's registerHandler(EventHandler*) be const? It does not change its member variables, but it does change global state.
Correct, it makes no guarantees about any other state than the object itself. And I would say that there's no particular requirement that it doesn't modify global state. [If you take it to extremes, any function call does modify the current state of the processor - even if it's just storing the return address on the stack [1]].
But a more reasonable thing would be that a const member function like this:
class myclass
{
private:
std::vector<int> v;
public:
std::vector<int> getV() const { return v; }
};
This will create a copy of the vector v - which in turn allocates memory (thus changing global state). An output function that feeds your object to a output stream would be a similar thing.
If a member function modifies some global state (in a way that isn't obvious), then it probably should be made clear in the description of the function (documentation is useful sometimes).
[1] Of course, the C++ and C standards do not state that the processor has to have a stack, return addresses, etc - the compiler could inline all the code, and not make any "calls" at all, or use magic to "remember" where to get back to - as long as the magic actually works, it's fine to rely on that.
Edit based on your edited question:
It's one of those that isn't entirely obvious in either direction, you would expect the registerHanlder to do something like "store the handler object somewhere". But since it's not modifiying the object itself, it may help to explain that it's updating the dispatcher class. Of course, if it's not actually updating the class itself, or using anything from the class, you probably should make it static rather than const - that way it's clear that it's not actually modifying the object itself.
Aside: As it is written, your code won't work, since EventDispatcher::registerHandler is not a static member, and your EventHandler::registerHandler is not referring to an instance of EventDispatcher. You would either have to make an instance of EventDispatcher as a global variable, or make EventDispatcher::registerHandler a static function and make mListeners a static member. Or something else along those lines.
What does the const keyword behind a method declaration guarantee?
The guaranty is a contractual reminder, rather than 'physical' memory barrier.
Thus, if you implement the const keyword correctly, the compiler will be able to help you to detect possible bugs.
However, no C/C++ compiler will stop you from modifying the member state directly; neither via fields nor by casting the object reference to a pointer and modifying the underlying memory.
Is my const method allowed to change (local/global) state?
A const method is not allowed to change the external behaviour of the system, but it is perfectly acceptable for a const method to change the internal state.
In other words, after calling all const methods randomly a couple of times, the system should still provide the same behaviour it did initially.
On the other hand, if the const method feels like caching a time consuming calculation and reuse it for the next call, it should be allowed. Same goes for a logger class that logs statistics, but does not change the behaviour of the system.
The question is, what would be the best or maybe a better practice to use. Suppose I have a function, which belongs to some class and this function needs to use some static variable. There are two possible approaches - to declare this variable as class's member:
class SomeClass
{
public:
....
void someMethod();
private:
static int m_someVar;
};
SomeClass::someMethod()
{
// Do some things here
....
++m_someVar;
}
Or to declare it inside the function.
class SomeClass
{
public:
....
void someMethod();
};
SomeClass::someMethod()
{
static int var = 0;
++m_someVar;
// Do some things here
....
}
I can see some advantages for the second variant. It provides a better encapsulation and better isolates details of an implementation. So it would be easier to use this function in some other class probably. And if this variable should be modified only by a single function, then it can prevent some erroneous data corruption from other methods.
While it's quite obvious, that the first variant is the only one to use when you need to share a static variable among several methods (class functions), the question pertains the case when a static variable should be used only for a single function. Are there any advantages for the first variant in that case? I can think only about some multi threading related stuff...
It's simple - use a static member if, logically, it belongs to the class (sort of like instanceCounter) and use a static local if it logically belongs to a function (numberOfTimesThisMethodWasCalled).
The choice of static or not depends completely on the context. If a particular variable needs to be common among all the instances of a class, you make it static.
However, if a variable needs to be visible only in a function and needs to be common across every call of the function, just make it a local static variable.
The difference between static data members and static variable in a function is that first are initialized at start-up and the second first time the function is called (lazy initialization).
Lazy initialization can create problem when a function is used in a muti-threaded application, if it is not required by the design I prefer to use static members.
I understand that one benefit of having static member functions is not having to initialize a class to use them. It seems to me that another advantage of them might be not having direct access to the class's not-static stuff.
For example a common practice is if you know that a function will have arguments that are not to be changed, to simply mark these constant. e.g.:
bool My_Class::do_stuff(const int not_to_be_changed_1,
std::vector<int> const * const not_to_be_changed_2)
{
//I can't change my int var, my vector pointer, or the ints inside it.
}
So is it valid to use static member functions to limit access. For example, lets say you have a function
void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
Well here we're not going to be accessing any member variables of the class. So if I changed the function to:
static void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
I'd now get an error, if I inadvertently tried to access one of my private var, etc. (unless I pass myself an instance of my class, which would be purposeful ^_^ !)
Is this a valid technique, similar to proactively making args that should not be changed constants?
What downsides might it have in terms of efficiency or use?
My chief reason for asking is that most of the "static" tutorials I read made no mention of using it in this way, so I was wondering if there was a good reason why not to, considering it seems like a useful tool.
Edit 1: A further logical justification of this use:
I have a function print_error,as outlined above. I could use a namespace:
namespace MY_SPACE {
static void print_error(...) {
...
}
class My_Class {
....
void a(void)
}
}
But this is a pain, because I now have to lengthen ALL of my var declarations, i.e.
MY_SPACE::My_Class class_1;
all to remove a function from my class, that essentially is a member of my class.
Of course there's multiple levels of access control for functions:
//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}
//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
Sure this is a bit atypical, but to lessening degrees so are using const functions and const variables. I've seen lots of examples where people could have used a const function, but didn't. Yet some people think its a good idea. I know a lot of beginning c++ programmers who wouldn't understand the implications of a const function or a static one. Likewise a lot would understand both.
So why are some people so adamantly against using this as an access control mechanism if the language/spec provides for it to be used as such, just as it does with const functions, etc.?
Any member function should have access to the other members of the object. Why are you trying to protect yourself from yourself?
Static members are generally used sparingly, factory methods for example. You'll be creating a situation that makes the next person to work with your code go "WTF???"
Don't do this. Using static as an access-control mechanism is a barbaric abomination.
One reason not to do this is because it's odd. Maintenance programmers will have a hard time understanding your code because it's so odd. Maintainable code is good code. Everybody gets const methods. Nobody gets static-as-const. The best documentation for your code is the code itself. Self-documenting code is a goal you should aspire to. Not so that you don't have to write comments, but so that they won't have to read them. Because you know they're not going to anyway.
Another reason not to do this is because you never know what the future will bring. Your print_error method above does not need to access the class' state -- now. But I can see how it one day might need to. Suppose your class is a wrapper around a UDP socket. Sometime in the middle of the session, the other end slams the door. You want to know why. The last messages you sent or received might hold a clue. Shouldn't you dump it? You need state for that.
A false reason to do this is because it provides member access control. Yes it does this, but there are already mechanisms for this. Suppose you're writing a function that you want to be sure doesn't change the state of the object. For instance, print_error shouldn't change any of the object's state. So make the method const:
class MyClass
{
public:
void print_error(const unsigned int error_no) const;
};
...
void MyClass::print_error(const unsigned int error_no) const
{
// do stuff
}
print_error is a const method, meaning effectively that the this pointer is const. You can't change any non-mutable members, and you can't call any non-const methods. Isn't this really what you want?
Static member functions should be used when they are relevant to the class but do not operate on an instance of the class.
Examples include a class of utility methods, all of which are static because you never need an actual instance of the utility class itself.
Another example is a class that uses static helper functions, and those functions are useful enough for other functions outside the class.
It is certainly fair to say that global scope functions, static member functions, and friend functions aren't quite orthogonal to one another. To a certain extent, this is largely because they are intended to have somewhat different semantic meaning to the programmer, even though they produce similar output.
In particular, the only difference between a static member method and a friend function is that the namespaces are different, the static member has a namespace of ::className::methodName and the friend function is just ::friendFunctionName. They both operate in the same way.
Well, actually there is one other difference, static methods can be accessed via pointer indirection, which can be useful in the case of polymorphic classes.
So the question is, does the function belong as "part" of the class? if so, use a static method. if not, put the method in the global scope, and make it a friend if it might need access to the private member variables (or don't if it doesn't)