C++: static variables not changing with static set() function - c++

After reading StackOverflow's discussions and implementing some advices, I have these pieces of code intended just to test the behavior of static members of a class.
Here is the header, which has the class declaration:
class OurClass
{
private:
static int x, y;
public:
static void setVals(int valx, int valy);
static int getValx();
static int getValy();
static void initialize();
};
And here is the cpp file, which has the definition of these members as well as the main() function:
#include <iostream>
#include "OurClass.hpp"
using namespace std;
void OurClass::initialize()
{
static int x = 0;
static int y = 0;
}
void OurClass::setVals(int valx, int valy)
{
static int x = valx;
static int y = valy;
}
int OurClass::getValx()
{
static int x;
return x;
}
int OurClass::getValy()
{
static int y;
return y;
}
int main(void)
{
OurClass::inicializa();
cout << "Provide x and y..." << endl;
OurClass::setVals(cin.get(), cin.get());
cout << "Value of x: " << OurClass::getValx() << endl;
cout << "Value of y: " << OurClass::getValy() << endl;
return 0;
}
So, assuming that a static variable exists for the class, and that static functions only access static variables, I was expecting that x and y would have the values that we read from the keyboard with the setVals() call in main(). But when printing their values in the couts, they still have the value we assigned in the initialize() function (which BTW was another suggestion I got here, that is, initialize a static variable in a method).
I am also unable to refer directly to the variables by OurClass::x or y even if I make them public.
Do you guys know why?

First you need to access your local class's static variable instead declaring new method local variables in each method. Check below.
class Out {
private:
static int x, y;
public:
void set(int x, int y);
int getSum();
};
int Out::x = 0;
int Out::y = 0;
void Out::set(int x, int y) {
Out::x = x;
Out::y = y;
}
int Out::getSum() {
return Out::x + Out::y;
}

Instead of setting values of existing variables this code creates new local static variables. Fix:
void OurClass::initialize()
{
x = 0;
y = 0;
}
void OurClass::setVals(int valx, int valy)
{
x = valx;
y = valy;
}
int OurClass::getValx()
{
return x;
}
int OurClass::getValy()
{
return y;
}
And add the definitions of those static variables in a .cc file (not header):
int OurClass::x;
int OurClass::y;

Related

How to use a variable from other functions

int calculateX()
{
int x;
cout<<"Enter value for x: ";
cin>>x;
return x;
}
int anotherFunction()
{
/////
}
int main()
{
calculateX();
anotherFunction();
return 0;
}
This is an example on a code. How do can I possibly use the input from the user in the calculateX() function into the function anotherFunction() ?
You have to use function parameters:
int calculateX()
{
int x;
cout<<"Enter value for x: ";
cin>>x;
return x;
}
int anotherFunction(int x)
{
/////
}
int main()
{
int x = calculateX();
anotherFunction(x);
return 0;
}
what you need is either a pass by value , which is already answered or a global variable like this
#include <iostream>
using namespace std;
// Global variable declaration:
int g;
int anotherFunction()
{
cout << g;
}
int main () {
// Local variable declaration:
int a, b;
a = 10;
b = 20;
g = a + b;
anotherFunction();
return 0;
}
A global variable can be accessed by any function. That is, a global variable is available for use throughout your entire program after its declaration.
You must declare the variable x global (outside the calculateX() function), so that anotherFunction() can see it. If you define the variable x inside the calculateX() function, it will be deleted after exiting the function.
int x;
int calculateX()
{
cout<<"Enter value for x: ";
cin >> x;
return x;
}
int anotherFunction()
{
/////
}
int main()
{
calculateX();
anotherFunction();
return 0;
}
Function generally has return type before it's name. For Example :
int calculateX() {
int x;
cout<<"Enter value for x: ";
cin>>x;
anotherFunction(x)
return x;
}
int is here return type.And you are calling two functions from your main function. calculateX has a variable of type int named x. So, you can't access x from outside of calculateX scope. But you can return it to your main function and store it in a different variable so that It becomes available in main function. Once It becomes available, you can send it as argument to another function . In your case It should be like this :
int anotherFunction(int valueFromMain)
{
std::cout << valueFromMain << std::endl;
}
int main(){
int returnedFromCalculateX = calculateX(); //You have returned value available on main Function
anotherFunction(returnedFromCalculateX); //Send It to anotherFunction(pass by value)
return 0;
}
You can also send the value as a reference. That needs a bit higher understanding. Please Check : https://www.w3schools.com/cpp/cpp_function_reference.asp for more details.

How to define a variable in a function and access and change it in another function?(c++)

I would like to know how to define a variable in one function and access and change it in another function.
For example:
#include <iostream>
void GetX()
{
double x = 400;
}
void FindY()
{
double y = x + 12;
}
void PrintXY()
{
std::cout << x;
std::cout << y;
}
int main()
{
GetX();
FindY();
PrintXY();
}
How would I access these variables from all the functions? (Obviously for this to work in real life I wouldn't need so many functions, but I think this is a nice simple example). Thanks in advance for your help!
Use function parameters to pass values to functions and return values to return results:
#include <iostream>
double GetX()
{
return 400;
}
double FindY(double x)
{
return x + 12;
}
void PrintXY(double x, double y)
{
std::cout << x;
std::cout << y;
}
int main()
{
double x = GetX();
double y = FindY(x);
PrintXY(x, y);
}
Since the question was tagged with C++, here is another option:
#include <iostream>
class Sample
{
public:
void FindY()
{
y = x + 12;
}
void PrintXY()
{
std::cout << x;
std::cout << y;
}
private:
double x = 400, y;
};
int main()
{
Sample s;
s.FindY();
s.PrintXY();
}
You want to define a variable in one function : That means you are making the variable local to that function.
You want to access and change that local variable from another function. This is not usual. Technically possible but can be done with better resource management/design.
*You can make the variable your class member and play with it.
*You can share a variable by making it global as well.
*In Tricky way :
double &GetX()
{
static double x = 400;
return x;
}
// We are accessing x here to modify y
// Then we are modifying x itself
// Pass x by reference
double &AccessAndChangeX(double& x)
{
static double y;
y = x + 12; // We are accessing x here and using to modify y.
// Let's modify x
x = 100;
return y;
}
void PrintXY(double x, double y)
{
std::cout << x;
std::cout << y;
}
int main()
{
double &x = GetX(); // Take the initial value of x. 400.
double &y = AccessAndChangeX(x);
//Print initial value of x and value of y(generated using x)
PrintXY(x, y);
// X was modified while AccessAndChangeX(x). Check if x was changed!
std::cout << "\n" << "What is the value of x now : " << GetX();
}
1st, make x, y as static, so that these exist when the function returns..
2nd, get reference, modify or do something outside the function..
#include <iostream>
double &GetX()
{
static double x = 400;
return x;
}
double &FindY( double x )
{
static double y;
y = x + 12;
return y;
}
void PrintXY(double x, double y )
{
std::cout << x;
std::cout << y;
}
int main()
{
double &x = GetX();
double &y = FindY( x );
// Now you can modify x, y, from Now On..
// .....
PrintXY( x, y );
}
By the way, I donot recommend this style of code..

linking error between two files c++

I have tried to call the class function computeCivIndex() from another class I have defined but it says that there was an undefined reference to LocationData::computeCivIndex(string, int, int, float, float) and a defined an unused funciton computeCivIndex(string int, int, float, float) in my LocationData.cpp
And I used g++ -Wall -W LocationData.h LocationData.cpp PointTwoD.h PointTwoD.cpp MissionPlan.cpp -o myProg.o to compile.
LocationData.h
static float computeCivIndex( string sunType_, int noOfEarthLikePlanets_, int noOfEarthLikeMoons_, float aveParticulateDensity_, float avePlasmaDensity_ ); /*calculate the possibility of life in the star system*/
};
LocationData.cpp
static float computeCivIndex( string sunType_, int noOfEarthLikePlanets_, int noOfEarthLikeMoons_, float aveParticulateDensity_, float avePlasmaDensity_ )
{
int sunTypePercent = 0;
float civIndex;
// convert string suntype to suntype percent
if (sunType_ == "Type O")
{
sunTypePercent = 30;
}
if (sunType_ == "Type B")
{
sunTypePercent = 45;
}
if (sunType_ == "Type A")
{
sunTypePercent = 60;
}
if (sunType_ == "Type F")
{
sunTypePercent = 75;
}
if (sunType_ == "Type G")
{
sunTypePercent = 90;
}
if (sunType_ == "Type K")
{
sunTypePercent = 80;
}
if (sunType_ == "Type M")
{
sunTypePercent = 70;
}
//compute the CivIndex
civIndex = ( (sunTypePercent/100) - (aveParticulateDensity_ + avePlasmaDensity_)/200 ) *
(noOfEarthLikePlanets_ + noOfEarthLikeMoons_);
return civIndex;
}
MissionPlan.cpp
float computeCivIndex[arraySize];
//compute civ index for all stored records
for (int i = 0; i < (entryNo+1); i++)
{
string suntype = locData[i].getSunType();
int earthlikeplanets = locData[i].getNoOfEarthLikePlanets();
int earthlikemoons = locData[i].getNoOfEarthLikeMoons();
float partdensity = locData[i].getAveParticulateDensity();
float plasdensity = locData[i].getAvePlasmaDensity();
locData[i].computeCivIndex(suntype,earthlikeplanets, earthlikemoons , partdensity, plasdensity);
point2d[i].setCivIndex(computeCivIndex[i]);
}
cout << "Computation Completed! ( " << entryNo <<" records were updated )" << endl;
That is because you have not implemented the function!
You need to qualify the function appropriately in the implementation to tell the compiler that you are actually implementing the class functions:
SomeClass.h:
class SomeClass
{
void someFunction();
static void someStaticFunction();
};
SomeClass.cpp:
void SomeClass::someFunction() { }
void SomeClass::someStaticFunction() { } // static must not be repeated!
If you do simply
void someFunction() { }
static void someStaticFunction() { }
you define two additional functions at namespace scope, not at class scope as you intended. By declaring them static, you additionally limit accessibility to from within the .cpp file they are defined in, so won't be found when compiling other .cpp files.
Be aware that static within a class has a completely different meaning than at global scope (and another different meaning within a function body) - Coming to that later. First, another error, though:
locData[i].computeCivIndex(suntype,earthlikeplanets, earthlikemoons , partdensity, plasdensity);
Via operator. (or operator-> on pointers), you can only call non-static functions (this is different from Java), static functions need to be called with class scope:
LocationData::computeCivIndex(suntype,earthlikeplanets, earthlikemoons, partdensity, plasdensity);
Meaning of static at different scopes:
class SomeClass
{
static void f(); // static class function as you know
};
static void anotherF(); // free/global function - static limits accessibility!
void yetAnotherF()
{
static int n = 0; // see below
}
static void anotherF(); is the C way to limit acessibility - the C++ variant of is placing the function into an anonymous namespace:
namespace
{
void anotherF() { }
}
Finally: static within functions: This way, you declare some kind of global variable that is only accessible from within the function. It is initialised only the first time you call the function, and the previous value of will be available on all subsequent calls:
void f()
{
static int x = 0;
printf("%d ", ++x);
}
int main()
{
f();
f();
f();
return 0;
}
Output will be: 1 2 3.
More details you find here.

Accessing double pointer from another class

I'd like to access to a double pointer which is located in another class "Board".
class Board
{
public:
Board(void);
Board(unsigned int xSize, unsigned int ySize);
~Board(void);
void SetObjectManager(ObjectManager* pObm);
void SetBlock(Block* block);
void LoadBoard(void);
void InitBoard(void);
//Other Functions...
private:
ObjectManager* m_obm;
Block* m_block;
//pointer to pointer to a int. (for 2 dimensional-array)
int **m_board;
};
First, the Board class. at the last line of class, you can see m_board.
I want to change this value in outside of this class.
Like this,
void Block::InitBlock(void)
{
int randPiece = Random::GIRand().RandInt(0, 1);
int randPos = Random::GIRand().RandInt(0, 10);
switch (randPiece)
{
case 0:
m_piece[2][1] = 1;
m_piece[2][2] = 1;
m_piece[2][3] = 1;
m_piece[3][3] = 1;
break;
//Other cases are here...
}
std::cout << "RandPos : " << randPos << std::endl;
std::cout << "RandPiece : " << randPiece << std::endl;
for (int y = 0; y < m_ySize; ++y)
{
for (int x = 0, pX = randPos; x < m_xSize; ++x, ++randPos)
{
if (m_piece[x][y] != 0)
m_board->SetBoardStatus(randPos, y, 1);
}
}
}
But, When I run this program, It blows up at SetBoardStatus(int, int, int)
SetBoardStatus looks like this,
void Board::SetBoardStatus(int x, int y, int value)
{
m_board[x][y] = value; //Visual Studio breaks the program here.
}
I allocate the double pointer properly.
And I set the board at the outside of this classes.
void Block::SetBoard(Board* board)
{
m_board = board;
}
And this is my block class.
class Block
{
public:
Block(void);
~Block(void);
void SetObjectManager(ObjectManager* pObm);
void LoadBlock (void);
void InitBlock (void);
void UpdateBlock (void);
void ReleaseBlock (void);
void SetBoard(Board* board);
private:
ObjectManager* m_obm;
Board* m_board;
int **m_piece;
int m_xSize;
int m_ySize;
};
Consider inheriting Block in Board; This will eliminate any possible de-referencing errors or bugs, as you can access the pointer right away.

C++ function pointer (class member) to non-static member function

class Foo {
public:
Foo() { do_something = &Foo::func_x; }
int (Foo::*do_something)(int); // function pointer to class member function
void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }
private:
int func_x(int m) { return m *= 5; }
int func_y(int n) { return n *= 6; }
};
int
main()
{
Foo f;
f.setFunc(false);
return (f.*do_something)(5); // <- Not ok. Compile error.
}
How can I get this to work?
class A{
public:
typedef int (A::*method)();
method p;
A(){
p = &A::foo;
(this->*p)(); // <- trick 1, inner call
}
int foo(){
printf("foo\n");
return 0;
}
};
void main()
{
A a;
(a.*a.p)(); // <- trick 2, outer call
}
The line you want is
return (f.*f.do_something)(5);
(That compiles -- I've tried it)
"*f.do_something" refers to the pointer itself --- "f" tells us where to get the do_something value from. But we still need to give an object that will be the this pointer when we call the function. That's why we need the "f." prefix.
class A {
int var;
int var2;
public:
void setVar(int v);
int getVar();
void setVar2(int v);
int getVar2();
typedef int (A::*_fVar)();
_fVar fvar;
void setFvar(_fVar afvar) { fvar = afvar; }
void insideCall() { (this->*fvar)(); }
};
void A::setVar(int v)
{
var = v;
}
int A::getVar()
{
std::cout << "A::getVar() is called. var = " << var << std::endl;
return var;
}
void A::setVar2(int v2)
{
var2 = v2;
}
int A::getVar2()
{
std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
return var2;
}
int main()
{
A a;
a.setVar(3);
a.setVar2(5);
// a.fvar = &A::getVar;
a.setFvar(&A::getVar);
(a.*a.fvar)();
a.setFvar(&A::getVar2);
(a.*a.fvar)();
a.setFvar(&A::getVar);
a.insideCall();
a.setFvar(&A::getVar2);
a.insideCall();
return 0;
}
I extended Nick Dandoulakis's answer. Thank you.
I added a function which set the member function pointer from outside of the class. I added another function which can be called from outside to show inner call of member function pointer.
Try (f.*do_something)(5);
#include<iostream>
using namespace std;
class A {
public:
void hello()
{
cout << "hello" << endl;
};
int x = 0;
};
void main(void)
{
//pointer
A * a = new A;
void(A::*pfun)() = &A::hello;
int A::*v1 = &A::x;
(a->*pfun)();
a->*v1 = 100;
cout << a->*v1 << endl << endl;
//-----------------------------
A b;
void(A::*fun)() = &A::hello;
int A::*v2 = &A::x;
(b.*fun)();
b.*v2 = 200;
cout << b.*v2 << endl;
}
I think calling a non static member of the class could also be done using a static member function.