static variable inside static method doesn't change - c++

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;
}

Related

Why aren't the member functions called by value like the normal functions in c++?

In c++, the changes done to the argument inside a function aren't reflected in the actual variable if
the return value of function is void, but that's not the case with the member functions where we can
see the changes happening permanently.
#include<iostream>
using namespace std;
class Student {
public:
int age;
float marks;
Student()
{
cout << "call by default";
}
void ageInc()
{
age = age + 1;
}
};
int main()
{
Student s;
s.age = 34;
cout << s.age << endl;
s.ageInc();
cout << s.age << endl;
return 0;
}
In c++, the changes done to the argument inside a function aren't reflected in the actual variable if the return value of function is void
Changes to an argument's value has nothing at all to do with a function's return type. A void function can quite easily make changes to its arguments. Whether or not those changes are reflected back to the caller has to do with whether the argument is passed by pointer/reference or not.
but that's not the case with the member functions where we can see the changes happening permanently.
A non-static class method receives a hidden this pointer to the object it is being called on. When the method accesses a non-static member of its owning class, it is using that this pointer to access the member. So any changes made to the member are done directly to the mmeber.
Your example is roughly equivalent to the following behind the scenes:
#include <iostream>
using namespace std;
struct Student {
int age;
float marks;
};
Student_ctr(Student* const this)
{
cout << "call by default";
}
Student_dtr(Student* const this) {}
void Student_ageInc(Student* const this)
{
this->age = this->age + 1;
}
int main()
{
Student s;
Student_ctr(&s);
s.age = 34;
cout << s.age << endl;
Student_ageInc(&s);
cout << s.age << endl;
Student_dtr(&s);
return 0;
}
Because you're not changing an argument. Your example function takes no arguments. You're changing a member variable.
You could think of all members of the object as being automatic passed-by-reference parameters, but this isn't how C++ encourages you to think of them.

Why isn't the static variable getting modified

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?

How to access int a declared in main in another function?

#include <iostream>
using namespace std;
void b();
int main() {
int a = 10;
b();
}
void b() {
int a;
cout<<"Int a="<<a;
}
I am looking to print the value of a in the main scope using a function, with my current code, it prints Int a=0. How can I achieve this?
Don't declare an entirely new a inside b().
Pass the a from main to b() and then print that.
For example:
#include <iostream>
void b(int whatever_name_you_want_here);
int main()
{
int a = 10;
b(a);
}
void b(int whatever_name_you_want_here)
{
std::cout << "Int a=" << whatever_name_you_want_here;
}
//Change your code to the following and it will give you the result you're looking for.
On your code there is no way to pass int a on the main to b(); unless b accepts a parameter of the type you want the function to output.
#include<iostream>
void b(int);
int main()
{
int a = 10;
b(a);
}
void b(int a){
std::cout << "int a=" << a;
}
I guess the main problem is not being aware of something very important which is called scope! Scopes are usually opened by { and closed by }
unless you create a global variable, it is only known inside the scope it has been introduced (declared).
you declared the function b in global scope :
void b();
so after this every other function including main is aware of it and can use it.
but you declared the variable a inside the scope of main:
int a = 5;
so only main knows it and can use it.
Please make note that unlike some other programming languages, names are not unique and not every part of the program recognize them in c and c++.
So the part:
void b() {
int a;
does not force the function b to recognize the a which was declared in main function and it is a new a.
so to correct this mistake simply give the value or reference of variable a to function b :
#include <iostream>
void b(int&);
int main() {
int a = 10;
b(a);
}
void b(int& a) {
std::cout << "Int a=" << a << std::endl;
}
please also note that the a as argument of the function b is not the same a in the function main.
The final tip is every argument for functions is known inside that function scope as it was declared inside the function scope!
What you want to achieve requires you to pass a value to a function. Let me give you an example on how to do that.
#include<iostream>
void print_value(int value){
std::cout << "Value is: " << value << '\n';
}
int main(){
int a = 5;
print_value(a);
return 0;
}
The only thing you are missing in your program is the parameter. I won't bother explaining the whole thing over here as there are numerous articles online. Here is a straightforward one.
Refer to this to understand how functions work in C++
Use pass by reference to access a variable which is declared in one function in another.
Refer the below code to understand the use of reference variable,
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
int main() {
int firstNum = 10;
int secondNum = 20;
cout << "Before swap: " << "\n";
cout << firstNum << secondNum << "\n";
// Call the function, which will change the values of firstNum and secondNum
swapNums(firstNum, secondNum);
cout << "After swap: " << "\n";
cout << firstNum << secondNum << "\n";
return 0;
}
#include <iostream>
using namespace std;
void displayValue(int number) {
cout<<"Number is = "<<number;
}
int main()
{
int myValue = 77;
displayValue(myValue);
return 0;
}

type defined in free function, accessible through auto outside. Language Bug or Feature?

Let's define a class inside a free function, and access it outside:
#include <iostream>
auto myFunc(){
class MyType{public: int i = 0; int j = 1;};
return MyType();
}
int main() {
auto my_type = myFunc();
std::cout << my_type.i << " " << my_type.j << "\n";
return 0;
}
It compiles, run as expected:
0 1
The name MyType is properly hidden:
if we replace auto, the following won't compile:
int main() {
MyType my_type = myFunc();
std::cout << my_type.i << " " << my_type.j << "\n";
return 0;
}
What does the standard say about it?
How to prevent it? The following code did not help:
namespace{
auto myFunc(){
class MyType{public: int i = 0; int j = 1;};
return MyType();
}
}
int main() {
auto my_type = myFunc();
std::cout << my_type.i << " " << my_type.j << "\n";
// your code goes here
return 0;
}
The standard doesn't say anything about this specifically, except that — as you've already pointed out — it's the name that has a scope, not the type. Use of auto bypasses the type's name, giving you a way to get at the type regardless of the name's scope.
It's kind of similar to how making a nested class private doesn't mean you can't use instances of it, only that you can't name it outside of the encapsulating class's scope.
I don't see how you'd "prevent" it, nor why you'd want to.

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.