Why isn't the static variable getting modified - c++

I'm creating a static variable 'a' inside a member function getobj() and returning it by reference and capture the reference in b. And I modify the same static variable 'a' in another member function mod(). When I print b, I should be expecting '2' right? Why isn't the static variable 'a' not modified to 2?
#include <iostream>
using namespace std;
class Test {
public:
int& getobj() {
static int a = 1;
return a;
}
void mod() {
static int a = 2;
}
};
int main(int arc, char* args[]) {
Test t;
int &b = t.getobj();
cout << "printing b first time and its value is expected : " << b << endl;
t.mod();
cout << "printing b second time after modifying and its value has not changed : " << b << endl;
return 0;
}
Output observed is
printing b first time and its value is expected : 1
printing b second time after modifying and its value has not changed : 1

The variable a in getobj() and the variable a in mod() are in different scope and are different things.
Therefore, modification to a in mod() won't affect a in getobj().

You could achieve your aim with the following piece of computational devilry:
void mod() {
static int& a = getobj();
a = 2;
}
Currently you have two different ints, both with static storage. Changing one will not change the other.
But did you want to use a class member variable instead (which is the normal thing to do), perhaps even without static storage duration?

Related

Can a function safely return a reference to an internal static variable?

Is it valid when a function returns by reference its own internal static variable?
const int& f() {
static int n=10;
return n;
}
Yes, there is nothing wrong with this. In particular, the static variable isn't destroyed when the function exits, so it doesn't return a dangling reference (as it would if n was not static).
Just keep in mind that it's a static variable, so for example in this:
#include <iostream>
const int& f(int x) {
static int n;
n = x;
return n;
}
int main() {
const int &a = f(1);
const int &b = f(2);
cout << a << " " << b;
}
a and b refer to the same variable, so this prints "2 2" and not "1 2".
This is fine. The static variable will be initialized the first time the function is executed, and will survive beyond the function's return.

static variable inside static method doesn't change

I want to create a class which has a static method that returns a reference to a static variable(which is declared inside the method). What I want is when calling the method to get the reference of the static variable. Then when I modify it outside the class and call the method again to get the same value I previously set.
Here's what I tried:
#include <iostream>
using namespace std;
class A
{
public:
static int& f()
{
static int i;
return i;
}
};
int main()
{
static int i;
i = A::f();
cout << i << endl;
i = 11;
cout << i << endl;
i = A::f();
cout << i << endl;
return 0;
}
The problem is that the output of this code is:
0
11
0
Press <RETURN> to close this window...
Why doesn't it return 0, 11, 11 and how can I make it return 0, 11, 11?
Note: I want the static variable to be explicitly declared inside the method and not as member.
Thanks!
This is because you copy the value returned by reference into a regular variable: when you store int& in an int, it is no longer a reference.
What you should do instead is
int &i = A::f();
Note that the local i needs not be static: reference to static data can be stored in automatic variables without a problem.
To have the local variable i refer to the same variable inside the function, declare it as a reference:
static int& i = A::f();
Otherwise, you're just creating a new variable and using assigning A::f() to it.
It needs to be an int& in main, if you want changes to that int to be changes to the int referred to by the return value of f.
You may want to initailce your variable. And you can use it directly or you may want to "conserv" the reference in a local reference.
But you can not reasign these local references. For example:
int main()
{
A::f()=3;
cout << A::f() << endl;
static int &i = A::f();
cout << i << endl;
i = 11;
cout << i << endl;
cout << A::f() << endl;
int &ii = A::f();
cout << ii << endl;
return 0;
}

static object initializer C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
file scope and static floats
What are static variables?
Here is a code from a book.
class X
{
int i;
public:
X(int ii = 0) : i(ii) {cout<<i<<endl;} // Default
~X() { cout << "X::~X()" << endl; }
};
void f()
{
static X x1(47);
static X x2; // Default constructor required
}
int main()
{
f();
return 0;
}
My question is why would I like to declare an object as static like in function f()? What would happen if I did not declare x1 and x2 as static?
For this code it makes no difference to the observable behavior of the program.
Change main to call f twice instead of only once, and observe the difference -- if the variables are static then only one pair of X objects is ever created (the first time f is called), whereas if they're not static then one pair of objects is created per call.
Alternatively, change main to print something after calling f. Then observe that with static, the X objects are destroyed after main prints (the static objects live until the end of the program), whereas without static the objects are destroyed before main prints (automatic objects only live until exit from their scope, in this case the function f).
The first time the function f() is hit the statics will be initialized (lazy loading). Had they not been declared static then they would be local variables and recreated every time you called function f().
All calls to f() will result in using the same x1 and x2.
The difference between
int f()
{
int i = 0;
++i;
return i;
}
int f2()
{
static int i = 0;
++i;
return i;
}
int main()
{
for (int i = 0; i < 10; ++i) { cout << f1() << ' ' << f2() << endl; }
}
Is that f1 will always make a new local variable i and set it to zero then increment it, while f2 will create a static local variable i and initialize it to zero once and then each call it increments it from the previous call value.
Here is some code to test what does a static object within a function mean:
#include <iostream>
using namespace std;
class A {
public:
void increase() {
static int b = 0;
b++;
cout << "A::increase: " << b << endl;
}
};
int main() {
A a;
a.increase();
a.increase();
a.increase();
return 0;
}
And the output is:
A::increase: 1
A::increase: 2
A::increase: 3
Notice the value of b is kept between function calls? Here is the example on ideone so that you can play with it.

member variable

Can there be a member variable in a class which is not static but which needs to be defined
(as a static variable is defined for reserving memory)? If so, could I have an example? If not, then why are static members the only definable members?
BJARNE said if you want to use a member as an object ,you must define it.
But my program is showing error when i explicitly define a member variable:
class test{
int i;
int j;
//...
};
int test::i; // error: i is not static member.
In your example, declaring i and j in the class also defines them.
See this example:
#include <iostream>
class Foo
{
public:
int a; // Declares and defines a member variable
static int b; // Declare (only) a static member variable
};
int Foo::b; // Define the static member variable
You can now access a by declaring an object of type Foo, like this:
Foo my_foo;
my_foo.a = 10;
std::cout << "a = " << my_foo.a << '\n';
It's a little different for b: Because it is static it the same for all instance of Foo:
Foo my_first_foo;
Foo my_second_foo;
Foo::b = 10;
std::cout << "First b = " << my_first_foo.b << '\n';
std::cout << "Second b = " << my_second_foo.b << '\n';
std::cout << "Foo::b = " << Foo::b << '\n';
For the above all will print that b is 10.
in that case, you would use the initialization list of test's constructor to define the initial values for an instance like so:
class test {
int i;
int j;
//...
public:
test() : i(-12), j(4) {}
};
That definition reserves space for one integer, but there'll really be a separate integer for every instance of the class that you create. There could be a million of them, if your program creates that many instances of test.
Space for a non-static member is allocated at runtime each time an instance of the class is created. It's initialized by the class's constructor. For example, if you wanted the integer test::i to be initialized to the number 42 in each instance, you'd write the constructor like this:
test::test(): i(42) {
}
Then if you do
test foo;
test bar;
you get two objects, each of which contains an integer with the value 42. (The values can change after that, of course.)

local variables of static member functions

Today we came accross a problem concerning static member functions in an multithreaded environment. The question we asked ourselves and couldn't find a satisfying answer is:
are local varialbes of static member functions static as well?
// header
class A
{
static int test();
}
// implementation
int A::test()
{
int a = rand();
int b = rand();
int c = a + b;
return c;
}
Say you have two threads both calling A::test(). Is it possible that while thread 1 proccesses c = a + b thread 2 enters test() and changes the value of a by assigning the new return value of rand() or in other words do both threads operate an the some memory locations for a, b and c?
No. The stack frames are independent for each thread's invocation of the function, and each gets its own locals. (You do need to be careful if you're accessing actual shared data e.g. static members in the class.)
Unless explicitly declared as static, no they're not. They're on a stack, and each thread has a separate stack.
The storage class of a, b, and c are (implicitly) auto which usually means on the call stack. They don't "inherit" static storage class from the method signature (which is a different meaning of static (yay for grossly overloaded keywords!)).
No, a, b, and c are not static.
Here's a sample that illustrates this:
class Val
{
public:
Val() { cout << "Val" << this << endl; }
~Val() { cout << "~Val" << this << endl; }
int n_;
};
class A
{
public:
static int test()
{
Val a;
a.n_ = rand();
Val b;
b.n_ = rand();
Val c;
c.n_ = a.n_ + b.n_;
return c.n_;
}
};
int main()
{
srand(time(0));
for( int i = 0; i < 5; ++i )
{
cout << "Test = " << A::test() << endl;
}
return 0;
}