Lets say I have a class with a static function. This function is called as static by another part of the code, without instantiating a class object. However, this static function also has in its code a dependance on variable x. x, however, is only initialized to a certain value or cleared in the constructor. But, given that no object of the class is instantiated, I believe that the variable is undefined. So, I have a few questions:
1) Is the constructor called at all?
2) Is the variable x undefined?
How can I work around a case like that?
In the example below, i'd want y to be 25, but can it ever be?
class CExample
{
public:
CExample(void);
~CExample(void);
static void foo();
int x;
};
CExample::CExample()
{
x = 5;
}
void CExample::foo()
{
int y = x*5;
}
Your code doesn't compile since the static function is using a variable which will only exist in objects instantiated by the class.
I'm not sure you've understood static. Only one static function exist. You can call it from anywhere. Which instance if CExample's x is it supposed to use?
This looks like a case of bad design. You could fix it so that it compiles by making x static and initialising it with 5. However you are probably a lot of better rethinking your design and what you want it to do. Remember there is only ever one instance of something that is static but there are as many instances of CExample as times you call it's constructor.
A static member function is a service of the class, not of a specific object of the class. A class's static data members and static member functions exist independently of instantiation of a object of that class.
The use of a static function will not call the constructor of its respective class, therefore your variable will not exist, causing a compilation error.
Just remember static member functions exist and operate independently of any objects of the class.
It's illegal to access a non-static member from a static function. See the output of gcc when I try to compile your program:
test.cpp: In static member function ‘static void CExample::foo()’:
test.cpp:9: error: invalid use of member ‘CExample::x’ in static member function
Related
I'm trying to understand why the following is an error:
class Foobar {
public:
static void do_something();
};
static void Foobar::do_something() {} // Error!
int main() {
Foobar::do_something();
}
This errors with "error: cannot declare member function 'static void Foobar::do_something()' to have static linkage" in g++, and "error: 'static' can only be specified inside the class definition" in clang++.
I understand that the way to fix this is to remove "static" in the definition of do_something on line 6. I don't, however, understand why this is an issue. Is it a mundane reason, such as "the C++ grammar dictates so", or is something more complicated going on?
The keyword static has several different meanings in C++, and the code you've written above uses them in two different ways.
In the context of member functions, static means "this member function does not have a receiver object. It's basically a normal function that's nested inside of the scope of the class."
In the context of function declarations, static means "this function is scoped only to this file and can't be called from other places."
When you implemented the function by writing
static void Foobar::do_something() {} // Error!
the compiler interpreted the static here to mean "I'm implementing this member function, and I want to make that function local just to this file." That's not allowed in C++ because it causes some confusion: if multiple different files all defined their own implementation of a member function and then declared them static to avoid collisions at linking, calling the same member function from different places would result in different behavior!
Fortunately, as you noted, there's an easy fix: just delete the static keyword from the definition:
void Foobar::do_something() {} // Should be good to go!
This is perfectly fine because the compiler already knows that do_something is a static member function, since you told it about that earlier on.
This question is already well answered. Details for static can be read here
Golden Rule:
The static keyword is only used with the declaration of a static member, inside the class definition, but not with the definition of that static member.
For future reference, to have the static method put the static method code above where it is called in the same file and define it as static. Also remove the class reference.
So instead of:
static void Foobar::do_something() {} // Error!
Use:
static void doSomething(){} // the Foobar is removed
It won't be able to access object values but just pass these in as parameters.
I have class with static string variable m.
class turbo
{
public:
static string m;
}
if I not declare like defined below I will get error undefined reference turbo::m.
string turbo::m;
Why I should declare it twice? I don't need to declare non static variables second time. Where is logic?
To be honest, I was surprised by this too the first time,
but found the very reasonable reason for it.
while member variables are stored within the object allocated space,
static members are not placed within the object memory space (either heap or stack)
but have a private shared space. just like functions do.
Therefore, declaring the static string m within the class.
is just like saying: there is a shared definition of this somewhere
and the name is turbo::m.
Hope this clears things up.
It's the difference between declaration and definition, very much like declaring a function with a forward reference, e.g.;
int MyFuncion();
and actually defining it with its function body, e.g.,
int MyFunction()
{
return 1;
}
I know you have an object and not a function, but conceptually, the declaration/definition idea is the same.
C++ forbids the definition of non-const static data members in the body of a class ("inline definition"). It becomes more obvious if you try to use an explicit constructor: for example,
class turbo
{
public:
static string m;
static string s = string("my_str"); // doesn't work
}
Hence, when you write static string m in the body of a class, it is merely a declaration, not a definition. You will have to define it later:
static string turbo::s = string("my_str");
In your case, you are simply invoking the default constructor in the definition:
static string turbo::m; // calls the default constructor
(Like any static variable, initialization occurs at the very start of your program, before main.)
Note that the definition must also occur only once (to avoid multiple definitions), so it must not appear in a header file.
In the class definition you only declare the static variable
class turbo
{
public:
static string m;
}
but it is not yet defined. To define the corresponding object you have to write
string turbo::m;
Now it will exist regardless of whether instances of the class were created.
I just noticed that we can access c++ static member function by member-selection operator (. or –>)
for example:
class StaticTest
{
private:
int y;
static int x;
public:
StaticTest():y(100){
}
static int count()
{
return x;
}
int GetY(){return y;}
void SetY(){
y = this->count(); //#1 accessing with -> operator
}
};
Here are how to use
StaticTest test;
printf_s("%d\n", StaticTest::count()); //#2
printf_s("%d\n", test.GetY());
printf_s("%d\n", test.count()); //#3 accessing with . operator
test.SetY();
what is the use case of #1 and #3?
what is the difference between #2 and #3?
Another style of #1 for accessing static member function in member function is
void SetY(){
y = count(); //however, I regard it as
} // StaticTest::count()
But now it looks more like this->count(). Is there any difference of two style calling?
Thanks
Have a look at this question.
According to the standard (C++03, 9.4 static members):
A static member s of class X may be referred to using the qualified-id
expression X::s; it is not necessary to use the class member access
syntax (5.2.5) to refer to a static member. A static member may be
referred to using the class member access syntax, in which case the
object-expression is evaluated.
So, when you already have an object and you're calling a static method on it, then there is no difference to using the class member access syntax.
If you however need to create the object first (be it by instantiating the object directly before, or by calling some function), then this creation process will of course take up a little extra time and memory. The this-Pointer, however, is never passed in to a static function, the call itself is always the same, no matter how it was written.
I'm a little confused about the answer to your first question, but with regards to your second question:
in #2 ( StaticTest::count() ), you used the count() method in a static manner, which means you called the function without creating a StaticTest object.
in #3 (test.count()), you created a StaticTest object called test, and called the method through the object (even though it was unnecessary.)
Functionally, there is no difference, but #2 is the preferred way of calling StaticMethods. Making an object when it is not needed is bad use of memory.
C++03, 9.4 static members
A static member s of class X may be referred to using the qualified-id expression X::s; it is not necessary to use the class
member access syntax (5.2.5) to refer to a static member. A static
member may be referred to using the class member access syntax, in
which case the object-expression is evaluated.
Objects and variables created in a static member function are not considered 'local' as they would in a member function, so that they can now be shared amongst multiple threads right?
Whereas if you have a member function which creates some object, this would be local to the thread and therefore it is non-shared.
Am I correct in saying this?
Consider this class
class CData
{
public:
static void func()
{
int a;
static int b;
}
int c;
static int d;
};
int main()
{
CData::func();
}
Now variable a is local to each call of func(). If two threads call func() at the same time, they get different versions of a.
b is a static local. The value persists between different calls of func(). If two threads call func() at the same time, they access the same version of b so they might need to do synchronisation.
c is an instance variable; it is attached to a particular instantiation of CData. func() cannot access c, except with a trick I'll show below.
d is a static variable. There is one instance of d shared between all uses of class CData so synchronisation may be necessary. It can be used easily from the static function func().
The trick used to access instance data from a static function is to pass a valid object into the function.
e.g.
class CData
{
public:
static void func(CData *p)
{
int a;
static int b;
b = p->c;
}
int c;
static int d;
};
int main()
{
CData data;
CData::func(&data);
}
Hope that helps.
No you are not correct.
Objects created in a static function are not shared, and this is also the case for any normal functions.
Objects can be shared though if they are declared static themselves, and it does not depends if the function is static or not.
void myFunc()
{
static MyObject o;
o.CallMethod(); // here o is shared by all threads calling myFunc
}
When an object is declared static, it is as if the object was a global variable, but only visible in the scope of the function that it is declared into.
No you are not correct. And yes, C++ does very much overuse the word "static".
A static class member variable is of course a global with the class acting as a namespace scope and with some access privilege differences if it is private or protected (can only be accessed by the class).
However a static class member function is just like a regular free-function (not class member) and has its own local variables every time it is called.
The only real difference between a static class member function and a regular free-function, apart from its naming convention, is that it has access to private members of a class (and needs an external "instance" of one).
In addition a static class member function can be called from a template with a variable template parameter, invoking what is commonly called "compile-time polymorphism" and is commonly used in meta-programming.
A static "local" variable in any function is a single-instance, on the other hand, is also a bit like a global and is sensitive to thread-contention issues as two threads calling the function access the same instance.
It does not matter if a function is static or not (class method). Only automatic variables can be seen as local to a function. If you have the address of those data, you may access it.
You can use e.g. thread-local storage to assign your output to a dedicated thread context.
This is an expansion of the scope of a previous question of mine.
What exactly is "static", how is it used, and what is the purpose of using "static" when dealing with C++?
Thanks.
It means that the variable is local to a translation unit (simply put, to a single source file), and cannot be accessed from outside it. This use of static is in fact deprecated in the current C++ Standard - instead you are supposed to use anonymous namespaces:
static int x = 0;
should be:
namespace {
int x = 0;
}
The keyword static has different meanings in C++, depending on the context.
When declaring a free function or a global variable it means that the function is not to be available outside of this single translation unit:
// test.cpp
static int a = 1;
static void foo() {}
If the result of compiling that translation unit is linked with a different translation unit containing symbols a and foo it will not break the One Definition Rule, as in this particular translation unit a and foo are private symbols. This use has been obsoleted by unnamed namespaces.
// test2.cpp
namespace {
static int a = 1;
static void foo() {}
}
When declaring a local variable within a function it means that the lifetime of the variable will extend from the first call to the function to the end of the program, and not only for the duration of the call:
int foo() {
static int counter = 0;
return ++counter;
}
int main() {
for ( int i = 0; i < 10; ++i ) {
std::cout << foo() << std::endl;
}
}
In the previous code, counter is initialized once when foo is called for the first time, but the variable will outlive the function and keep the value across different function calls. The previous code will print "1 2 3 4... 10". If the variable was not declared static then the output would be "1 1 1... 1".
Within a class scope, static means that the member is a member of the class, and not of a particular instance. This use is equivalent to the use in your other question: usage of that particular member is not bound to any specific object.
struct test {
int x;
static int y;
};
int test::y; // need to define it in one translation unit
int main() {
// test::x = 5; // !error cannot access a non-static member variable
// without an instance
test::y = 5; // ok
test t, other;
t.x = 10; // ok
t.y = 15; // ok, the standard allows calling a static member through
// an instance, but this is the same as test::y
}
In this case, the member x is a non-static member attribute, and as such there is a different x for each instance of the class. In the sample program t.x and other.x refer to different integers. On the other hand y is static and thus there is a single instance of test::y in the program. Even if the standard allows to call t.y and other.y both uses refer to the same variable. The same goes with member methods. If they are static they are class-level methods and can be called without an instance, while if they are non-static they are applied to a concrete instance and the a.b or a->b syntax must be used.
This use of static is similar to the use of the same keyword in Java, while the other two are not present in that language. There is one use of the keyword in Java that is not present in C++, and that is the use of static class initializers (a block of code at class level surrounded by static { ... }). In Java that block of code will be executed when the class is loaded and only once. Initialization of static member variables in C++ must be done in the initializer of the variable definition.
This stuff seems to be fairly well covered here.
But to paraphrase, there are 2 uses in C
Prevent the use of a global variable outside the scope of the file that defines it.
Allow local variables within a function to persist accross invocations of the function, as in
int getNextId()
{
static int id = 0;
return id++;
}
C++ inherits both of these, and adds two uses of its own.
static member variables: Variables that are "shared" accross all instances of a class, and can also be accesses without reference to an instance of the class. Shared seems like the wrong word, but in essence I beleive that the result is that any reference to a static member variable references the same memory location.
static methods: Methods that can be called without reference to a specific instance of the class that defines it.
Static basically means that a variable is tied to the lifetime of the program and not of any given function or class instance. When should you use it? Don't. What is the purpose? Debugging data, mostly.
Generally, in C++, if you find yourself using static data, you've done it wrong. There are times when it's appropriate, but they're very rare.
When static is used in a class in C++, it means more or less the same thing that it does in Java. For variables it means that one one instance of the variable exists for all classes and for functions, it means that the function does not implicitly access the this pointer at all.
In C and C++ when static is used for a global variable or function, then it means that the variable may only be referenced in the current C or C++ file. In other words, the compiler must not generate any relocation symbols for the variable or function.
When static is used next to a variable in a local function, it means that the variable does not go out of scope but will retain its value from function-call to function-call. The variable become effectively a global variable that can only be accessed from the given function.
Static class members are data and functions that are associated with the class itself, rather than with the objects of the class.
In the following example, class Fred has a static data member x_ and an instance data member y_. There is only one copy of Fred::x_ regardless of how many Fred objects are created (including no Fred objects), but there is one y_ per Fred object. Thus x_ is said to be associated with the class and y_ is said to be associated with an individual object of the class. Similarly class Fred has a static member function f() and an instance member function g().
class Fred {
public:
static void f() throw(); <-- 1
void g() throw(); <-- 2
protected:
static int x_; <-- 3
int y_; <-- 4
};
(1) Member function associated with the class
(2) Member function associated with an individual object of the class
(3) Data member associated with the class
(4) Data member associated with an individual object of the class
Usage:
When you want to keep tract of the number of instances of a class created you use static variable. For example in a 'Car' class each Car instance may have a unique serial number(_y in this case) and the company may want to keep track of the number of cars produced(_x in this case).