Is there a way to initialize a variable in a function and save its value for next call of function?
I'm making application in qt and i have one function connected with a signal. I want an variable in that function to change after the other one reaches its goal. Here is the body of that function:
void objekt::advance(int phase)
{
if(!phase) return;
QPointF location = this->pos();
if (int(location.x())==200 || int(location.x())==-200)
{
smijer=-smijer;
}
setPos(mapToParent(smijer,0));
}
I defined the smijer variable as static int. But i dont'know how to initialize it only once, when program starts, and how to keep its new value after each call of the function.
Your answer is in your question basically. Static variables (either a class member or local variable of a function) is initialized only once where it is terminated. For example;
#include <iostream>
int foo () {
static int sVar = 5;
sVar++;
return sVar;
}
using namespace std;
int main () {
int iter = 0;
do {
cout << "Svar :" foo() << endl;
iter++;
}while (iter < 3);
}
if you write a program like that it will print out Svar values just like;
Svar :6
Svar :7
Svar :8
So as you see although we call foo function three times the initialization of a static varible is done only once.
Why am I being downvoted? He wants to change a variable and preserve the states after function calls. (He doesn't specify whether the variable is a member of the class or anything, so I'm assuming it's not. I'll change my answer if he clarifies and states his question less ambiguously.)
You're going about this wrong. To keep a variable after a function's scope ends, you have to allocate it on the heap rather than the stack. You can use new or malloc to do this, but you also have to free this memory with delete and free, in that order.
With new and delete:
#include <iostream>
void modify(int * p){
(*p)++;
}
int main(void){
int * pointer = new int;
*pointer = 5;
std::cout << *pointer << std::endl;
modify(pointer);
std::cout << *pointer << std::endl;
delete pointer;
return 0;
}
And with malloc and free:
#include <iostream>
#include <cstdlib>
void modify(int * p){
(*p)++;
}
int main(void){
int * pointer = (int*)malloc(sizeof(int)); //DO NOT CAST IN C
*pointer = 5;
std::cout << *pointer << std::endl;
modify(pointer);
std::cout << *pointer << std::endl;
free(pointer);
return 0;
}
new does provide facilities for deleting arrays quickly and is better overall for normal use C++.
If smijer is a member of class objekt, then do it like this:
objekt.h:
class objekt
{
...
static int smijer;
...
};
objekt.cpp
int objekt::smijer = YOUR_INITIALIZATION_VALUE;
On the other hand, if you want/need smijer to be a global variable, then do it like this:
globals.h:
extern int smijer;
globals.cpp //Or another .cpp file
int smijer = YOUR_INITIALIZATION_VALUE;
Although in this case I'd stick it in a namespace. In this case it isn't declared static but it does have the lifetime of your program.
Declare the variable as static inside the function and the valued will be remembered. You don't need to initialize it. But you can if you want to.
Related
#include <iostream>
using namespace std;
class MyStaticClass{
public:
static int value;
MyStaticClass(){
value++;
}
~MyStaticClass(){}
};
int MyStaticClass::value;
void main(){
MyStaticClass::value = 0;
for (int i = 0; i<9; i++)
MyStaticClass *c = new MyStaticClass();
cout << MyStaticClass::value;
system("pause");
}
Please explain me why the result is 9, and when replace MyStaticClass *c = new MyStaticClass() with MyStaticClass c() the result changes to 0? Finally what is the meaning of int MyStaticClass::value;, why when i delete that line the compiler shows error? Thanks everyone!
The line int MyStaticClass::value; tells the compiler to reserve storage for the static variable value. If you don't do that then the linker will fail.
The result is 9 since the for loop body executes 9 times: you are creating 9 new instances of MyStaticClass (which isn't really a static class, it just has a static member). Note that you ought to delete all these objects else your program leaks memory.
MyStaticClass c(); declares a function prototype for a function c that takes no parameters and returns a MyStaticClass: it does not create an object. This is nicknamed the most vexing parse. Since no object is created, value stays at 0. It would have been a different matter had you written MyStaticClass c;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have got a code:
void fun1(int ** i) {
*i = new int(0);
}
void fun2(int *& i) {
i = new int(69);
}
int main()
{
using namespace std;
int a = new int(42);
fun1(&a);
cout << "fun1" << a << endl;
fun2(&a);
cout << "fun2" << a << endl;
}
And I want to pass "a" into functions fun1 and fun2. Can I do it without creating a pointer that will point to a? Can I pass "a" somehow?
One of the functions takes a pointer to a pointer:
void fun1(int ** i)
the other one takes a reference to a pointer:
void fun1(int *& i)
Calling them without having a pointer variable is rather pointless, as those functions main effect (most likely) is to change the adress the passed pointer (passed by reference, either as pointer or reference) is pointing to so that it can be used by the caller.
Lets suppose the following would work
int a;
fun1(&(&a));
The function would change the adress the "temporary" (&a which is a pointer to int) is pointing to, but you would have no means to access it.
1st of all int a = new int(42); is wrong the operator new creates the object on the heap and returns the pointer to the newly created object. you are trying to assign it to an int. at best it should look like int* a = new int; *a = 42; at which time your code is responsible for deleting it.
Now if you have a function like void func(int* pA) {} and have a local variable like int a = 42; and you want to pass it to your function, you would call your function like func(&a);.
2nd both your functions are creating memory leak. you are creating a new pointer that is never deleted.
3rd if you want to change the value of a in your functions, all you need is something like this:
void func1(int* pA)
{
*pA = 42;
}
or you can do something like this:
void func2(int& rA)
{
rA = 42;
}
I think you have not understood the meaning of pointer and references.
To have a reference without pointer, just do foo(int &a) {a = 43} and call the function like this: foo(a)
Operator new returns pointer, so you must write int* a = new int(42);. After you can call the functions as follows:
fun1(&a);
fun2(a);
And also don't forget to delete allocated memory with new:
#include <iostream>
void fun1(int ** i)
{
delete *i;
*i = new int(0);
}
void fun2(int *& i)
{
delete i;
i = new int(69);
}
int main()
{
using namespace std;
int *a = new int(42);
fun1(&a);
cout << "fun1: " << a << endl;
fun2(a);
cout << "fun2: " << a << endl;
delete a;
}
or Mrs.,
in C++, I'm thinking about using a subroutine to define all my pointers first declared in my main body. I know it can be done by using functions to return one pointer each time. Hence, I still want to do it in a subroutine. I googled much and haven't found a answer yet. Your help is appreciated.
An sample c++ code is as:
#include <iostream>
using namespace std;
void testsub(int* k3d)
{
k3d= new int [10];
cout<<"test 0 "<<k3d[0]<<endl;
}
int main ()
{
int* i3d=0;
testsub(i3d);
cout<<"test 1 "<<i3d[0]<<endl;
}
I hope the i3d in the main body can be used after the dummy pointer k3d has been defined in the subroutine.
Thanks a lot in advance.
The pointer needs to be passed in by reference, otherwise you're just changing a local copy of that pointer.
void testsub(int*& k3d)
Also you need to call delete[] after the coutstatement, to avoid memory leaks:
delete [] i3d;
Alternatively, you could return a pointer from a subroutine.
#include <iostream>
int* testsub()
{
int* ptr = new int[10];
std::cout << "test 0 " << ptr[0] << std::endl;
return ptr;
}
int main()
{
int *i3d = testsub();
cout << "test 1 " << i3d[0] << endl;
delete[] i3d;
return 0;
}
Or use a std::vector to hold a collection of integers. In this case you don't need to worry about memory allocations/deallocations too.
#include <vector>
#include <iostream>
int main()
{
std::vector<int> i3d(10);
std::cout << "test 1 " << i3d[0] << std::endl;
return 0;
}
I'm trying make number guessing game with qt creator. I need to access a variable from another function. I was able to do that on python by adding "self." to beggining of variable but I can't do it on C++. Here's a sample what I am trying to do:
void function1()
{
int i;
}
void function2()
{
I need to access i here.
}
Thanks for help.
You could use pointers, classes or global variable ( I'd recommend pointers or a class tho)
void f1(int *iPtr)
{
cout << "value= " <<*iPtr << endl;
}
void f2(int *iPtr)
{
*iPtr = *iPtr + 5; // access ( modify ) variable here
cout << "after addition = " << *iPtr << endl;
}
int main()
{
int i = 5;
int *iPtr;
iPtr = &i; // point pointer to location of i
f1(iPtr);
f2(iPtr);
// after f1() value of i == 5, after f2() value of i == 10
}
I believe the equivalent behavior in C++ would be a member variable.
If you're not already, I'd suggest using a class. So, in your header file define it something like this:
class MyClass {
public:
void function1();
void function2();
private:
int i;
};
If you're not using C++ classes, then you can define "i" in the header file but that will make it global - in essense. And, probably not the best practice.
It is not possible to access a variable from another function since they exist only on the stack and they are destroyed when the function exits. Use a global variable.
You could declare i as a global variable and just assign it the random number once you have chosen it. That way you could still generate a random number and use it in another function.
int i;
void function1()
{
int randNum;
// get random number here
i = randNum;
}
void function2()
{
// do stuff with i here
}
For example:
#include <iostream>
#include <deque>
int func(int a){
std::deque<int> obj;
obj.push_back(a);
for(std::deque<int>::iterator it = obj.begin(); it!=obj.end();++it)
std::cout << *it << '\n';
return 0;
}
int main()
{
int x=2;
func(x);
func(x);
}
output is :
2
2
so its mean that deque object destroy after reach end scope of func. And i cant do nothing with this, except return value or add to global scope? No way to change behavior of this object with adding static to him or static pointer or something else? I mean that with pure C++ its look like :
int func(int a){
static int *p = new int;
}
and value will be store between function calls but how to do same with stl containers i don't know.
If you really want it to be static, make it so:
static std::deque<int> obj;
although this is probably a bad idea: conceptually, you have hidden state in the program, and practically, there's a possibility of accessing the object after it's been destroyed. (You can fudge around the lifetime issues by using dynamic allocation and leaking the object, as demonstrated in Drax's answer, if you really want to go down this particular road of pain).
Better would be to encapsulate the state in a class. Then you can control exactly when it's created and destroyed, and have more than one instance if you like.
class thing {
public:
int func(int a) {
obj.push_back(a);
// and print it
}
private:
std::deque<int> obj;
};
int main() {
thing t;
t.func(2); // 2
t.func(3); // 2 3
}
If you want to remember data between function calls, store it elsewhere, or as a last resort make it static.
So, either go with Mike Seymour's answer to make it a member of a class, or hold onto it in main, and pass it to the function, making sure you pass by reference if you wish to change it:
int func(int a, std::deque<int> & obj){
//.. as you were
}
From main, make the data and pass it in:
int main()
{
int x=2;
std::deque<int> obj;
func(x, obj);
func(x, obj);
}
Simply :
int func(int a){
static std::deque<int>* obj = new std::deque<int>;
obj->push_back(a);
for(std::deque<int>::iterator it = obj->begin(); it!=obj->end();++it)
std::cout << *it << '\n';
}
But i'm not sure that's a good idea :)