I have a few questions about the static keyword in C++ (and probably with other languages as well.) What is the purpose of declaring a function as static?
void static foo(int aNumber) {
... }
How about a static inline function?
void static inline foo(int aNumber) {
... }
Is there any benefit to using the static keyword with a function, and do those benefits apply to class functions as well?
I realize some datatypes like structs and arrays have to be static when compiling with an older compiler, but is there any point when using a new ANSI-C++ compiler (like MS VC++ 2008)? I know that using a static variable inside a loop saves time by keeping the data in memory and not reallocating memory every loop iteration, but how about when a variable is declared only once, like at the top of a header file or within a namespace?
Depends on Context:
Like many things in C++, static means different things depending on its context.
It's very common in C++ for the same word to mean different things depending on its context.
For example:
* is used for multiplication, dereferencing a pointer, and creating pointers.
& is used to get the address of variables, to declare a reference, and as a bitwise AND operator.
Global use of static:
If you declare a function or variable as static outside of a class and in global scope, it is specific to only that file. If you try to use that variable or function in a different file (via a forward declaration) you will get a linking error.
Example:
a.cpp:
static void fn()
{
cout<<"hello a!"<<endl;
}
b.cpp:
void fn();
void gn()
{
fn();//causes linking error
}
This feature allows you to use a function that no other file will ever see, that way you don't cause possible linker errors of a symbol defined multiple times. The preferred method to do this is with anonymous namespaces though:
a.cpp:
namespace
{
void fn() // will be static to a.cpp
{
cout<<"hello a!"<<endl;
}
}
Inside of a class use of static:
If you declare a function or variable as static inside of a class (or struct), it is a class function or class variable. This means that there is only one for that whole class. A class function can only use class variables. A class variable is shared amongst all instances of that class.
class C
{
public:
static void fn()
{
y = 4;//<--- compiling error
// can't access member variable within a static function.
}
int y;
}
This is a great feature to use if you have something that is specific to the class of your objects, but not specific to an instance.
Inside a function use of static:
If you declare a variable as static inside of a function, you can consider that the variable value will persist upon calls. It will only be initialized once.
Example:
//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
static int x = 0;
cout << x << endl;
x++;
}
I personally try to avoid this, and you probably should to. It is not good to have global state. It is better to have functions that given the same input guarantees the same output.
Just like in the English language:
The concept of context sensitive meaning is not specific to C++, you can even see it in the English language.
I am going to screen a movie (Means showing the movie)
The screen on the TV is broken (Means a part of the TV)
Other meanings in other programming languages:
Depending on the programming language there can be a different meaning, but the first thing most people think of when you say static is a class variable/function vs a member variable/function.
I hang around on the ##c++ irc channel on irc.freenode.net and I really like the clarification on static that the bot nolyc is programmed to give. I quote word for word:
When used inside a function, the
static keyword indicates that a
variable is shared between all calls
of the function. When used inside a
class, it indicates that the variable
or function is a member but is not
tied to a specific instance. When
used inside a namespace, it specifies
internal linkage.
I hope that clears things up. I haven't answered all your questions. I would say that you should use the static keyword to do what it was intended to do. Use it as a tool to accompolish your task, if it is the right one for the job. As far as benefits go, I wouldn't worry. If you need to optimize, then think about those effects if there is no other resort.
I hope this helps.
Related
It comes across as odd to me that local function definitions are illegal. As things stand now, I doubt it would be too hard to implement, and the erasure of what could be a potential feature (like in python for example) for no reason at all seems strange, especially for a language like C++, where you can shoot yourself in the foot if you want to. The illegality of local function definitions seems doubly so strange if things like this are allowed.
int main()
{
void func(); // Allowed?
class BypassRules {
public:
static void func() { return; }
};
BypassRules::func();
func();
return 0;
}
void func() { return; }
Oddly enough, local function 'Declarations' are allowed, but definitions are not. And the rule on local function definitions not being allowed can be easily bypassed by writing a class encapsulator. So, could I have some clarification? Why are local class definitions classified as 'illegal' in C++?
Oddly enough, local function 'Declarations' are allowed, but definitions are not. And the rule on local function definitions not being allowed can be easily bypassed by writing a class encapsulator. So, could I have some clarification? Why are local class definitions classified as 'illegal' in C++?
Illegal because they don't make much sense, whether it may be defining a function inside a function or a class inside a function like main().
But then you can always use workarounds, such as:
For functions you can always use a lambda, which acts as an anonymous temporary function, can be called inside main plus be used within function parameters as well.
It can be invoked whenever necessary and subsequently discarded like a throw-away function, but it does the job - whatever you would expect from a function.
Example:
int main()
{
// Define within the scope of main()
auto temp = [](int x)
{ std::cout<< x;
}
temp(10); // call like a function
}
For classes, use static functions, (being local to the translation unit) with public access specifiers (as you did in your question).
Example:
int main()
{
class temp
{ public:
static void a()
{ std::cout<< 10;
}
};
temp::a();
}
Output for both cases: 10
Provided there are alternatives approaches like the ones above to define a function/class/struct inside main(), there isn't really much of a point to make them legal. ¯\_(ツ)_/¯
I define a lot of classes in my cpp files. Often with unimaginative names, such as 'Implementation'. and am worried about name collisions, as these are horrible to debug (assuming the compiler silently drops one of the definitions). However, I also want to be able to debug my program, so anonymous namespaces are not an option. So, can file-scoped (aka. translation-unit scoped) classes be defined in c++ without using namespaces? If yes, how?
File-scoping in c
In c, one can create a global variable with int foo;, and limit the variable to file-scope using static int foo;. Similarly, file-scoped functions are also created with the static keyword, for example static void bar();. And structs do not define data or executable code, and thus are effectively always file-scoped.
Virtual member functions
Now c++ introduced virtual member functions, which caused structs (aka. classes) to contain data and executable code. Hence structs are now globally defined. However, it is not allowed to use static to make the struct file-scoped again. I.e. static struct Foo{}; does not compile.
Namespaces
To tackle the problem of name collisions, c++ also introduced named namespaces. Those can also be used to wrap the struct, such that it becomes pseudo-file-scoped. Though this still forces you to pick a unique name (that you don't even care about) for every file. As a solution, they also introduced anonymous namespaces. Unfortunately, neither gdb nor the visual studio debugger seem to support anonymous namespaces (it is basically impossible to refer to anything inside the anonymous namespace).
A partial solution is to use anonymous structs/classes and typedef these, as both are file-scoped (C - Limit struct Scope), except that it is impossible to explicitly define constructors or destructors (Constructor for a no-named struct). The following example compiles and runs fine with gcc and also allows gdb to put a breakpoint on method():
interface.h:
struct Iface {
virtual void method()=0;
};
implementation_a.cpp and implementation_b.cpp:
#include "interface.h"
typedef struct : Interface {
virtual void method();
} Implementation;
void Implementation::method() {
// Do stuff...
}
Interface * new_implementation_a() { // or new_implementation_b
return new Implementation();
}
main.cpp:
#include "iface.h"
int main() {
Interface * a = new_implementation_a();
Interface * b = new_implementation_b();
a->method();
b->method();
return 0;
}
I've been learning C++, and I've come across static variable (I have prior knowledge from C89), and in the resource i'm using, they've declared a static variable in a class such as:
class nameHere
{
public:
static int totalNum;
}
int nameHere::totalNum = 0;
int main()
{}
For Example.
What I don't understand is that, since I've already declared that the static variable is an integer in the class definition, why do I need to also declare it as an integer outside of the class definition?
Would it not make sense to simply initialise it like so:
nameHere::totalNum = 0;
int main()
{}
Is there a particular reason or simply a convention of C++?
Thanks for all the help!
This would (probably) make the language even more difficult to parse (and it's already almost insanely difficult to parse anyway).
As it is, the datatype (int, long, my_class, whatever) tells the compiler that what it's seeing is the beginning of a declaration (which, in this case, is also a definition). Without that, the compiler would have a rather more difficult time sorting things out.
In the specific case of things at global scope, it wouldn't be that bad, because at global scope about all you can have is a series of declarations. At any other scope, however, things would be more difficult (and having one rule at global scope, and another elsewhere would be ugly indeed).
In C++11 you can simply initialize the variable inside the class:
class nameHere
{
public:
static const int totalNum = {0};
}
There is a difference between a definition and a declaration.
While the static variable in the class has been declared, it has not been defined. The One Definition Rule, explains declarations and definitions and states
In any translation unit, a template, type, function, or object can have no more than one definition. Some of these can have any number of declarations.
Therefore, the full type of the object must be used when declaring the variable.
I though I had a good understanding of how C++ worked but I'm confused about a piece of its use. If I declare a class instance globally in a .cpp file (not associated with a class) like
Class b(constructor parameters)
it doesn't cause a problem. My understanding was that declaring classes this way allocated them in the stack frame for the method they were in instead of on the heap. But if I declare this globally there is no method and thus no stack frame right? Why am I allowed to do this and more importantly what is happening and is this any kind of big no no in C++?
It is just a static object. It is treated like any other global variable.
It will not be tied to any stack frames and will be created when the anything in the file is loaded for the first time.
Generally, people will not recommend relying on globals from a design perspective. It depends though, they can be reasonable.
If you are doing any sort of threading they can be an issue. You also want to minimize different parts of your application knowing that things are global variables, it leads to a lot of spaghetti code.
If the variable is not referenced outside of the file, or for cross-cutting concerns, then sometimes it can be a good thing.
The best advice is to avoid it when you can, don't over design it when you can't.
Objects that are global variables (or more precisely variables "at namespace scope") have static storage duration. This means they live until the end of the program, and they are initialized during program startup (either during the static or the dynamic initialization phase).
The order of initialization is not generally specified except that all such global objects are initialized before main() is called, and that the initialization does not introduce data races.
(Common techniques to sequence mutually dependent global initialization is to replace naked global variables with a global getter function and a block-static variable:
Foo & getFoo() { static Foo impl; return impl; }
Now any other global using getFoo() in its own constructor will be initialized after impl.)
Quick Comment
You may want to change your post's title to:
Declaring a Global Class Instance in a C++ file ?
or:
How does a global object, its declared, and, later, stored in memory, in C++ ?
I may be wrong, but, seems to me, like you have work with other Object Oriented, programming languages, reference based, and try to apply your experience on C++.
Example
C++, its a mix of: Procedural Programming & Object Oriented Programming, and some other stuff, like functional.
You may want to see a Procedural Program, as a single object, which class has been already declared & make an instance. and, has this public main method, automatically executed, like a constructor.
When you read a C++ file like this:
// file: "example.cpp"
// class declaration without local variables
class CoordinateClass
{
int x;
int y;
};
// a global variable
CoordinateClass MyCoordinates;
int main (char[][] args)
{
// dont care about this in this example
int ErrorCode = 0;
// DoSomething();
// dont care about this in this example
return ErrorCode;
} // int main()
You may want to think as this:
// file: "example.cpp"
public: class example: program
{
public:
// class declaration without local variables
class CoordinateClass
{
int x;
int y;
};
// a global variable, works like a field of a class
CoordinateClass MyCoordinates;
int main (char[][] args)
{
// dont care about this in this example
int ErrorCode = 0;
// DoSomething();
// dont care about this in this example
return ErrorCode;
} // int main()
};
// this is done automatically:
example MyExample;
MyExample.main();
Cheers.
Even though there are no static classes in C++, coming from a Java background I use to create a helper class like Util containing only static methods. Is this considered bad style or usual practice? One alternative I see is to use C functions (no class context at all). What other alternatives are there? What are there advantages and disadvantages and under which circumstances would I use any of these.
defining bunch of static methods in c++ suggests namespacing static functions as one alternative, though I fail to see what effects the static keyword without class context has.
If you want to create a collection of utility functions without clobbering the global namespace, you should just create regular functions in their own namespace:
namespace utility {
int helper1();
void helper2();
};
You probably don't want to make them static functions either.
Within the context of a non-member function (as opposed to a member function), the static keyword in C and C++ simply limits the scope of the function to the current source file (that is, it sort of makes the function private to the current file). It's usually only used to implement internal helper functions used by library code written in C, so that the resulting helper functions don't have symbols that are exposed to other programs. This is important for preventing clashes between names, since C doesn't have namespaces.
In C++, classes with only static methods is mostly used in template metaprogramming.
For example, I want to calculate fibonacci numbers at compile-time itself, and at runtime I want them to print only, then I can write this program:
#include <iostream>
template<int N>
struct Fibonacci
{
static const int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
static void print()
{
Fibonacci<N-1>::print();
std::cout << value << std::endl;
}
};
template<>
struct Fibonacci<0>
{
static const int value = 0;
static void print()
{
std::cout << value << std::endl;
}
};
template<>
struct Fibonacci<1>
{
static const int value = 1;
static void print()
{
Fibonacci<0>::print();
std::cout << value << std::endl;
}
};
int main() {
Fibonacci<20>::print(); //print first 20 finonacci numbers
return 0;
}
Online demo : http://www.ideone.com/oH79u
C++ is a multi paradigm language, so if you need some util functions that perhaps don't really fit in a class at all, then I would just make them free functions. I don't see a reason to put them into a class, just for OOP's sake.
There is no advantage that I can see to making all functions static and putting them in a class, over having them just as free functions. Personally, I think free functions are then an easier to work with option.
As many others have pointed out, free functions inside a namespace is an approach that's often taken for this sort of thing in c++.
One case I'd make for classes with all static functions is when you'd like to expose a set of functions to information derived from template parameters, i.e.
template <typename Ty>
class utils
{
public :
// if you need to setup a bunch of secondary types, based on "Ty" that will be used
// by your utility functions
struct item_type
{
Ty data;
// etc
};
// a set of utilities
static void foo(Ty &data1, item_type &item)
{
// etc
}
};
You can use this to achieve the effect of a template'd namespace:
int main ()
{
double data;
utils<double>::item_type item ;
utils<double>::foo(data, item);
return 0;
}
If you're not using templates just stick with namespaces.
Hope this helps.
There is no real issue with declaring static methods within a class. Although namespaces are more suitable for this purpose for the reasons mentioned in the post you are referring to.
Using C functions can generate name collisions, unless you decide on a naming convention, prefixing your functions with stuff, for example btFunctionA, btFunctionB etc.
You will want to keep your symbols within namespaces to avoid that, you are using C++ and not C after all.
Static functions within a namespace aren't any different from non-static. I believe the static keyword is simply ignored in this context.
In C++, just make them free functions. There's no need or reason to place them in a class at all. Unless you're doing shizzle with templates.
This may be relevant to your interests. It is an article that, uh, examines the different approaches to classes and functions in Java compared to other languages.
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
There is one other situation in which a static class might be preferred to a namespace: when you want to make the data private so that it can't be directly modified from outside the class/namespace, but for performance reasons you want to have have public inline functions that operate on it. I don't think there is any way to do that with a namespace, other than by declaring a class inside the namespace.