Sharing static variables across files: namespace vs class - c++

There are a lot of questions about static vs global here but I think my question is a bit different.
I want to know if there is a way to share a variable placed in a namespace across files the way static variables in a class can.
For example, I coded this:
//Foo.h
class Foo
{
public:
static int code;
static int times_two(int in_);
};
namespace bar
{
static int kode;
}
-
//Foo.cpp
int Foo::code = 0;
int Foo::times_two(int in_)
{
bar::kode++;
code++;
return 2*in_;
}
-
//main.cpp
int main()
{
cout << "Foo::code = " << Foo::code << endl;
for(int i=2; i < 6; i++)
{
cout << "2 x " << i << " = " << Foo::times_two(i) << endl;
cout << "Foo::code = " << Foo::code << endl;
cout << "bar::kode = " << bar::kode << endl;
if(i == 3)
{
bar::kode++;
}
}
}
All that yielded this for code and kode:
Foo::code = 1,2,3,4
bar::kode = 0,0,1,1
Once again, is there a way to share a variable placed in a namespace across files the way static variables in a class can? The reason I ask is because I thought I would be able to shield myself from confliciting global variables by using :: notation, and just found out I could not. And like any self-disrespecting programmer, I believe I am doing it wrong.

Yes:
//bar.h
namespace bar
{
extern int kode;
}
Outside of a class or struct, static has a whole different meaning. It gives a symbol internal linkage. So if you declare the same variable as static, you will actually get a different copy for all translation units, not a unique global.
Note that you'll need to initialize the variable once:
//bar.cpp
namespace bar
{
int kode = 1337;
}

Related

Accessing variables from other classes (C++)

I have been trying to access a series of integers from the main class, and then display them inside a method.
However, I've been having a bit of trouble with this due to my own ineptitude with a language I've not been coding in for too long.
After quite a bit of searching, I have been unable to find anything that can help me. How would I go about doing this, if it's possible at all?
#include "inventory.h"
inventory::inventory(){
int maxhealth = 100;
int maxmana = 0;
int health = 100;
int mana = 0;
int level = 1;
int agility = 1;
int strength = 1;
int healthpotions = 0;
int manapotions = 0;
int armourlevel = 0;
int weaponlevel = 0;
int crystals = 0;
int gold = 0;
int rock = 0;
int wood = 0;
}
string inventory::getinv(){
return inventory; //I know this sort of return thing won't work, just a placeholder until I figure out what to do.
}
This is what I have been using thus far, but I'm having a hard time even getting that to not display the "Member 'X' was not initialized in this constructor." I'm clearly doing something quite wrong.
Inventory.h:
#ifndef INVENTORY_H_
#define INVENTORY_H_
#include <iostream>
class inventory{
private:
int maxhealth;
int maxmana;
int health;
int mana;
int level;
int agility;
int strength;
int healthpotions;
int manapotions;
int armourlevel;
int weaponlevel;
int crystals;
int gold;
int rock;
int wood;
public:
inventory();
string getinv();
};
#endif /* INVENTORY_H_ */
EDIT: Thanks to the help so far I've been able to get rid of most of the errors. The only one left is "..\src\zoria.cpp:1616:36: error: 'rock' was not declared in this scope"
You do not need the type in the constructor to access the member variables, otherwise the compiler would think that you are trying to declare new local variables.
Here is a basic correction for the inventory.cpp file:
#include "inventory.h"
inventory::inventory(){ // this is the constructor
maxhealth = 100;
maxmana = 0;
health = 100;
mana = 0;
level = 1;
agility = 1;
strength = 1;
healthpotions = 0;
manapotions = 0;
armourlevel = 0;
weaponlevel = 0;
crystals = 0;
gold = 0;
rock = 0;
wood = 0;
}
string inventory::getinv(){
return "inventory"; //I know this sort of return thing won't work, just a placeholder until I figure out what to do.
}
Note the "" added to the placeholder (return "inventory") to make it a valid string.
Note: You cannot access the variable that is in a class directly without an object of the class, even if it is declared public (static being the only exception). However you have declared all your member variables as private and will thus require getter and setter functions to access their values.
EDIT:
Classes are like containers which contain things. But just the definition of a class is just like a stencil which can be used to create objects of that type. The actual existence of the object occurs when you write inventory someobject;.
Now every class has a special function called the constructor which goes by the name of the class itself and is called as soon as the an object of this class is declared. You can initialize all member variables of the class in the constructor.
To access the members of a class you have to use the . dot operator. Members have to be declared public if they need to be directly accessed outside the class' body.
So you change the class definitions like this:
inventory.h:
#ifndef INVENTORY_H_
#define INVENTORY_H_
class inventory{
public:
int maxhealth;
int maxmana;
int health;
int mana;
int level;
int agility;
int strength;
int healthpotions;
int manapotions;
int armourlevel;
int weaponlevel;
int crystals;
int gold;
int rock;
int wood;
inventory();
void printinv();
};
#endif /* INVENTORY_H_ */
and
inventory.cpp:
#include "inventory.h"
#include <iostream>
using namespace std;
inventory::inventory()
{
maxhealth = 100;
maxmana = 0;
health = 100;
mana = 0;
level = 1;
agility = 1;
strength = 1;
healthpotions = 0;
manapotions = 0;
armourlevel = 0;
weaponlevel = 0;
crystals = 0;
gold = 0;
rock = 0;
wood = 0;
}
void inventory::printinv(){
cout << "LEVEL: " << level << endl;
cout << "HEALTH: " << health << endl;
cout << "MANA: " << mana << endl;
cout << "AGILITY: " << agility << endl;
cout << "STRENGTH: " << strength << endl;
cout << endl;
cout << "HEALTH POTIONS: " << healthpotions << endl;
cout << "MANA POTIONS: " << manapotions << endl;
cout << endl;
cout << "ARMOUR LEVEL: " << armourlevel << endl;
cout << "WEAPON LEVEL: " << weaponlevel << endl;
cout << "CRYSTALS: " << crystals << endl;
cout << endl;
cout << "GOLD: " << gold << endl;
cout << "ROCK: " << rock << endl;
cout << "WOOD: " << wood << endl;
}
Now declare the object of the class in main like:
inventory inv;
and access every member variable (such as maxhealth, maxmana, health, mana, level, agility, strength, healthpotions, manapotions, armourlevel, weaponlevel, crystals, gold, rock and wood) like:
inv.gold = 10;
inv.rock++;
etc. throughout the code.
and to display the inventory replace all the redundant display code with:
inv.printinv();
everywhere.
See zoria.cpp here, I have done the changes for all display code and changed the variable accesses for: maxhealth, maxmana, health and healthpotions you also have to do it for the rest of the variables like: mana, level, agility, strength, manapotions, armourlevel, weaponlevel, crystals, gold, rock and wood.
Hope this helps. Tell if there are any more questions.
In Inventory.h you define the member variables (maxhealth, maxmana etc) and in Inventory.cpp, you should declare them in its constructor. The problem is that you're redeclaring them. Try removing the "int" from every variable in the constructor because you only need to specify the type when you define the variable.
A few points here:
In you constructor you are shadowing the instance variables by method-local re-definition of identically named variables. Please, look up on how to initialize instance member variables in constructors.
You try to implicitly convert an instance of your inventory class into a std::string with the signature of your getinv() method, but you have not defined any operator for this kind of conversion.
(probably related to (2)) From the error you posted, I assume you are using getinv() something along the line of
inventory my_inventory{};
int inv = my_inventory.getinv();
This will not work as there is no implicit conversion from std::string to int defined. Change the return type of inventory::getinv() to int and return an actual int there.

How to instantiate a variable from a class with a variable from another class with C++

I'm trying to instantiate a variable Tt1 from a class called ÌnletConditions with the variable Tt0 from another class with the object ein_in.
double InletConditions::Tt1 = ein_in.Tt0;
The variable Tt1 is declared as public static double in the headerfile of the class InletConditions.
class InletConditions {
public:
static double Tt1;
}
The variable Tt0 is declared and instantiated like this:
\\ file Eingabe_Konstanten.h
class Eingabe_Konstanten {
public:
static double Tt0;
}
\\ file Eingabe_Konstanten.cpp
double Eingabe_Konstanten::Tt0 = io_ein.read(1);
io_ein.read(int) refers to a method, which reads in a value from the specified line number (int) from a file. The value should become 293.15.
How can I achieve that the value of Tt1 also becomes 293.15? In the output it is just 0.
int main() {
Eingabe_Konstanten ein;
InletConditions in;
std::cout << ein.Tt0 << endl;
std::cout << in.Tt1 << endl;
}
Output:
293.15
0
I would be pleased if anyone could help me, since I am new to programming and don't know what topic this problem is related to.
Thanks in advance.
Static variables refer to the class itself and not to a particular object of that class. As such you must call them using the scope resolution operator of the class:
InletConditions::Tt1 = Eingabe::Tt0;
std::cout << Eingabe::Tt0 << endl;
std::cout << InletConditions::Tt1 << endl;
LIVE DEMO
Why not just use:
int main() {
Eingabe_Konstanten ein;
InletConditions in;
in.Tt1 = ein.Tt0; //You need to assign the value of ein.Tt0 to in.Tt1 here
std::cout << ein.Tt0 << endl;
std::cout << in.Tt1 << endl;
}

How to access info from an instance from another instance in c++?

I am just started learning OOP concepts and to help myself learning, I have created a Characters class. From this class I have made instance called main and an instance called monster. Here is the code for the class:
#include <iostream>
#include <string>
using namespace std;
class Character {
public:
string name;
float health;
int attackLevel;
int defenseLevel;
void setAttr(string sName,float sHealth, int sAttackLevel, int sDefenseLevel) {
name = sName;
health = sHealth;
attackLevel = sAttackLevel;
defenseLevel = sDefenseLevel;
}
void attack(int whatInstanceToAttack) {
whatInstanceToAttack.hitpoints -= 20; //obviously not valid but how do i do this?
return whatInstanceToAttack;
}
int defend(string defend) {
int damageRelieved = defenseLevel * 2;
return damageRelieved;
}
};
int main() {
Character main;
Character monster;
main.setAttr("Rafael",200,100,30);
monster.setAttr("Monster1",30,40,30);
cout << "Default Values for Raf are;" << endl;
cout << main.name << endl;
cout << main.health<< endl;
cout << main.attackLevel << endl;
cout << main.defenseLevel << endl;
cout << "Default values for monster are" << endl;
cout <<monster.name << endl;
cout <<monster.health << endl;
cout << monster.attackLevel<< endl;
cout << monster.defenseLevel << endl;
return 0;
}
Basically what I want to do is somehow access the monster instance via the main instance. I want to do this by running the attack method. So if I run
main.attack(monster);
then I want the monster to lose 20 hitpoints.
How do I go about doing this?
All you need is to pass reference of Character in attack method.
I think you must be aware of pass by value and pass by reference concept. If not you can read it here
void attack(Character &whatInstanceToAttack) {
whatInstanceToAttack.hitpoints -= 20; //obviously not valid but how do i do this?
}
Yes you can access the variables of an instance from another instance of the same class. You need to use a reference to the object to ensure the changes are reflected in the other instance. So here is what your attack function should look like.
void attack(Character &c)
{
c.hitpoints - = 20;
}
Now when you call main.attack(monster) from the main() function, the hitpoints of monster will get decremented by 20.
As a side note, it is considered a good practice to make the data members of a class private, to avoid illegal access/modification of the data. Always use the member functions as an interface to your class instances.
overload the method attack and you can pass by value or reference as per your requirement.
void attack(Character chr)
or
void attack(Character &chr)

references in c++ with static

Below is a output question.I am not able to understand why its answer is 30.
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
static int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
OUTPUT:30
Can anybody tell why output is coming to be 30 and also can explain the role of static keyword
In computer programming, a static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program
void foo()
{
int a = 10;
static int b = 10;
a++;
b++;
std::cout << "a : " << a << " , b : " << b << std::endl;
}
A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable.
int a = 4;
int b = a;
int &c = a;
c++;
std::cout << "b = " << b << std::endl; //4
std::cout << "a = " << a << std::endl; //5
std::cout << "c = " << c << std::endl; //5
/* Becaues c is a refence to a, it means that
a and c are just different names to the same memory location
so updating either one updates the actual value in memory
*/
a++;
std::cout << "c = " << c << std::endl; //6
std::cout << "a = " << a << std::endl; //6
//consider the function below:
int &bar()
{
static int a = 5;
std::cout << "a is " << a << std::endl;
return a;
}
Testing the two:
int main()
{
for (int i = 0; i < 3; i++)
foo();
//for every call of foo():
//memory allocation for a is created and deleted when a goes out of scope
//memoery allocation for b extends through out the life of the program
//bar() returns a reference to "a" i.e
int reference_to_a = bar(); //prints 5
reference_to_a = 30;
bar(); //prints 30
bar() = 50; //prints 30 and later assigns 50 to the reference returned.
bar(); //prints 50
}
static make the variable persist across function calls.
which means static int x = 10; will be executed once when func is called for the first time.
int static_test()
{
static int x = 10;
x++;
return x;
}
static_test(); // first call will return 11
static_test(); // second call will return 12 because the value of x ( was saved and was then incremented)
static_test(); // third call will return 13
Now, you need to understand what reference are. To understand what reference are you need to understand pointers. I am guessing you will easily find some website explaining those two.
case 1:
#include<iostream>
using namespace std; //namespace std is being used
int &fun()
{
int x = 10; //x is static
return x;
}
int main()
{
fun() = 30;
cout << fun(); //fun() called
return 0;
}
Here, in the call fun(), we are declaring a local variable int x, which goes out of scope once it returns from fun().
so, in the line cout << fun() a new variable is declared and address of the new variable is returned.
case 2:
static int x = 10;
here, since variable 'x' is static, it can be initialized only once. i.e., the first time x is initialized to 5 and then over written to 30.
now when you are making the function call subsequent times, static int x = 5 is ignored. Hence, it returns the value 30

accessing the member of a class of pointer array of another class

I'm trying to figure out how I can or why I can't access the member of this class. First I'll show you what works so you know what I'm thinking, then I'll show you what I can't seem to do.
What I can do is this: I have a class with a member. I make an pointer array of that class and make NEW pieces of it (through loop) and that's fine and all. I can also make another class with a similar array and even make NEW instances of that as well and initialize them, but when I try to access them, I have problems.
This code almost works fine:
#include <iostream>
using namespace std;
class testClass{
public:
int number;
};
class testPoint{
public:
testClass testInstance;
testClass *testclassArray[5];
void makeArray();
void setToI();
};
void testPoint::makeArray(){
for (int i = 0; i < 5; i++){
testclassArray[i] = new testClass;
}
}
void testPoint::setToI(){
for (int i = 0; i < 5; i++){
(*testclassArray[i]).number = i;
}
}
int main(void){
testPoint firstTestPoint;
firstTestPoint.makeArray();
firstTestPoint.setToI();
// EXCEPT FOR THIS LINE this is where I have problems
cout << firstTestPoint.(*testclassArray[0]).number << endl;
return 0;
}
I know this should work becuase this works
int main(void){
testPoint firstInstance;
firstInstance.testInstance.number = 3;
cout << firstInstance.testInstance.number << endl;
// and this works
return 0;
}
and this works
int main(void){
testClass *testPointer[5];
for (int i = 0; i < 5; i++){
testPointer[i] = new testClass;
(*testPointer[i]).number = i;
}
cout << (*testPointer[0]).number << endl;
return 0;
}
so why can't I access the members on the cout function the same way?
The following is invalid syntax:
cout << firstTestPoint.(*testclassArray[0]).number << endl;
The most common way to write what you are trying to accomplish is:
cout << firstTestPoint.testclassArray[0]->number << endl;
But, if you prefer, you can also write:
cout << (*firstTestPoint.testclassArray[0]).number << endl;
(The second way is far less common.)
The . operator is used to access members of direct objects, e.g. a.member where a might be declared as struct A a;. The -> operator is used to access members of indirect objects (aka pointers to objects), e.g. b->member where b might be declared as struct B* b = new B();.
You are dereferencing the variable in an incorrect way.
Try doing
cout << firstTestPoint.testclassArray[0]->number << endl;
instead.
In the same way the second attempt, where it works for you, could also have been written:
out << testPointer[0]->number << endl;
Try using this code:
cout << firstTestPoint.testclassArray[0]->number << endl;