If you have data for a class that will be modified and needs to be retained throughout the program, but is only used in one member function, is it preferred to make that variable a local static variable of the routine that it is in or make it a member of the class?
The question isn't "will the data be used throughout the program", but rather "if you make two objects of this class, do you want them to share this data?" If yes, make it static. If no, don't.
I would argue that in most cases, you should never use a local static variable, and instead use a static member variable. Then the question degenerates to if that variable should be shared among the class instances or not.
Declaring a local variable as static means your method now has state, separate from the object's state. It can lead to many mistakes when maintaining this code (such as copy constructor implementation, assignment, serialization) and when reading it (unclear method behavior).
Avoid using static locals unless you have some good reason (the only one I can think of is single threaded singletone implementation).
Related
I've read some answers in SO and tutorials in other places that generally give the following idea:
Reference variables can be used as a second name or an alias for another variable
Is that indeed true or are there situations where it is either not possible or not convenient to do so? When is it viable and how to make it so?
The motivation for my question:
I followed this notion inside variables of a class and ended up with a problem whenever objects of those classes were copied (The references inside the copied objects would refer to the original variables). The solution I've seen so far involves specifying a custom copy constructor to change the initialization of those aliases from the default, which can be a lot of work since you can't extend the default constructor to change those specific variables and you are then required to write one for your entire class or for a nested one that wraps your aliases ( and thus also limits the names you can use).
Bottom-line, as far as I know, using reference member variables as aliases is either unsafe (it won't work as expected if your variable is copied) or not easy( you may have to write and maintain a lot of code).
Having said that, my question can be split as follows:
Can member reference variables be used as aliases without all the trouble mentioned earlier?
Are there any other situations where they can be unsafe? ( besides in copy operations)
When you don't have a member reference variable, can you indeed safely use them as a second name or is there a situation where extra care should be taken?
References are safe when:
What they are referencing cannot go away before the reference goes out of scope.
That's it.
Examples of this are:
A. Parameters to a function which will not store the references anywhere.
B. Aliasing a deeply nested or computed element in a container to make code cleaner.
C. Inside a functor that has temporary lifetime (such as a custom printer object)
At almost Any other time you should either be using a copy or a shared pointer.
As I understand, each instance of a class has its own member variables in memory, so that it can store different values for different objects. However, it is not the same for member functions. Member functions are reused across objects of a class, so it only has one address with one block of memory to refer when needed by all objects.
Static function is made to access static members. However, static function also exists only one during the lifetime of its application. Aside from being the static accessor, at low level it is not different with normal class functions, isn't it? Or maybe I'm wrong, that each class has its own functions?
Non-static functions accept additional parameter, this, which is the pointer to the class instance with the instance-specific variables.
Static functions don't have this parameter (thus you can't use this in a static function and can only access static data members).
This differs from language to language, but in C or C++03 functions generally map on assembly functions; that is they exist once in memory (whether free functions, class functions or class static functions) and take arguments as parameters, including a this pointer for member functions that is implicit.
In C++11, lambda functions introduce a novelty: each instance of the so-called function will carry some state. From an implementation point of view, it therefore means that a "regular" function needs be created and it is associated to an anonymous bundle of data (if necessary). The function need not be duplicated each time the lambda is created, but the data does. One helpful figure is to remember that lambdas (in C++) replace function objects (or predicate objects): they are just syntactic sugar, the implementation is similar.
The only difference between static and member functions is that member functions always have the this pointer passed in automatically.
simply if it is referred, static functions creates a single set of memory for itself and are meant for static data-members which are generally not changeable. But non-static functions creates separate set of memories for each instances and are meant for both non-static and static data-members. If u require stable output go for static and if u require the alternate go for the non-static.
What is the Design and Performance impact for making all functions static which do not touch the member variable of the class?
You should actually consider making them non-static free functions, as explained in detail in this question. This question is also very interesting.
In a nutshell, these question explain that you should prefer non-friend non-member functions whenever possible (meaning when they do not access non-public members).
What are Design and Performance impact for making all function static which do not touch member variable of class?
performance: static member functions may be slightly faster than non-static member functions because they don't need to pass a this pointer, but you're unlikely to notice the difference; where inlining is used there may not be one. Further, pointers to a static function may be used directly, whereas "pointers" to non-static member functions are typically offsets/indices and require a this pointer for use; the run-time CPU operations involved can be expected to be slightly more complicated.
design: the choice between static and non-static member function can safely be made on the basis of the need to access an object's non-static member data in order to fully perform the expected operation. If you're generally comfortable with OOP and it doesn't seem intuitive and sensible to call the function using the notation object.fn(x, y, z) - that the function lends itself to being perceived as an operation on the current state of that specific object - then it probably shouldn't be a non-static member.
Ignoring the question as I understand it and looking at the wider terrain, free functions do have their own advantages as discussed in other replies; countering that the tighter association of static members can help programmers find potentially useful routines - all depending on the tools and habits they have.
Performance-wise, static member functions are faster and use less stack space because they do not need to pass a this pointer. But this isn't a significant cost.
Regarding design, you should ask yourself why the functions are members of the class if they do not access its data members? There certainly are design patterns that include static functions. However, a widely favored approach to class design is to choose the minimum number of functions necessary to expose the functionality of the class while keeping its data hidden. This makes it easier to change the internals of the class without knock-on changes to the code which uses the class. Such an approach has little use for static functions as they cannot provide access to the data.
Absolutely yes. The non-static member functions are meant to cater the non-static member variables. If variables are not used then the function should be made static which makes your design cleaner and you can avoid passing this as the 1st hidden argument (which betters the performance a little).
[Note: On funny side there is one notable exception:
struct A {
virtual void foo (int) = 0;
};
Even though you don't have member used inside foo() you can't make it static ! :)]
Sometimes it makes sense to make a function virtual even if it does not access any instance members - for example to return some class-related properties (something like virtual bool eatsPlants() in the animal class hierarchy). Then it cannot be static because there are no virtual static members in C++.
Performance of static member functions vs free functions?
There is absolutely no performance difference between static member functions and free functions.
Performance of static member functions vs non static member functions?
Typically static member function are used to eliminate the need for an object and eliminate the extraneous this argument and that is the only performance advantage over non static member functions but it is hardly noticeable.
It depends. First, of course, if the function is to be virtual, then it
can't be static. (Most of the member functions I have which don't touch
a member variable are virtual. Otherwise, why make it a member at all?)
Otherwise, it depends on the role of the function in the class. If it
is fundamentally independent of any instance of the class (e.g. it sets
some global parameter of the class, which affects all instances), then
it should be static; such functions should be fairly rare, however. If
on the other hand, it only incidental that it doesn't touch a member
variable;, if conceptually, it does involve the specific instance, then
make it a member. (This is frequent in the case of virtual functions,
but probably very rare otherwise.)
Say, I develop a complex application: Within object member functions, should I modify only those objects, that are passed to the member functions as parameters, or can I access and modify any other objects I have access to(say public or static objects)?
Technically, I know that it is possible to modify anything I have access to. I am asking about good practices.
Sometimes, it is bothering to pass as an argument everythying i will access and modify, especially if I know that the object member function will not be used by anybody else, but me. Thanks.
Global state is never a good idea (though it is sometimes simpler, for example logging), because it introduces dependencies that are not documented in the interface and increase coupling between components. Therefore, modifying a global state (static variables for example) should be avoided at all costs. Note: global constants are perfectly okay
In C++, you have the const keyword, to document (and have the compiler enforce) what can be modified and what cannot.
A const method is a guarantee that the visible state of an object will be untouched, an argument passed by const reference, or value, will not be touched either.
As long as it is documented, it is fine... and you should strive for having as few non-const methods in your class interface and as few non-const parameters in your methods.
If you have a class with member variables, then it is entirely acceptable to modify those member variables in a member method regardless of whether those member variables are private, protected, or public. This is want is meant by encapsulation.
In fact, modifying the variables passed into the member method is probably a bad idea; returning a new value is what you'd want, or getting a new value back from a separate member method.
I have heard that using static member objects is not a very good practice.
Say for example, I have this code:
class Foo {
...
static MyString str;
};
I define and initialize this variable in the implementation file of this class as:
MyString Foo::str = "Some String"; // This is fine as my string API handles this.
When I run this code, I get a warning:
warning:'Foo::str' requires global construction.
I have quite much of such members in my class, what is the best way to handle this.
Thanks,
Most of the arguments against them are the same as for global variables:
Initialization order between different compilation units is undefined.
Initialization order inside one compilation unit may affect the behavior — thus non trivial ordering may be required.
If a constructor throws an exception you can't catch it, your program is terminated.
APPENDED: To handle this properly you must either make sure that above points don't apply to your code and ignore the warning, or redesign your program: Do you really need them static? Why not use const char* Foo::str = "Some String";?
The biggest reason for concern with this example is that constructing the static member object happens before main() and destruction happens after main() (or when you call exit()). So far, that's a good thing. But when you have multiple objects like this in your program, you risk a bug where code attempts to use an object that has not yet been constructed or has already been destroyed.
The C++ FAQ Lite has some helpful discussion on this topic, including a workaround/solution. Recommended reading is questions 10.14 through 10.18. 10.17 is most directly applicable to your example.
Using a static member, you are not guaranteeing thread safety, imagine two threads trying to access the static member - now what would be the value of that member - was it the one from thread x or thread y, this also induces another side-effect, race conditions, where one thread modifies the static member before the other thread completes... in other words, using a static member can be hazardous...
As an example, it is required to know the number of instances of a class. This would require a class static member to track the count of instances.
There is nothing wrong in having a static member of a class if the problem solution requires such a design. It's just that the nitty gritties have to be taken care as mentioned in other posts.