C++ Initialize Class based global variables - c++

I am trying to define few global variables which should be available all functions but would like to initialize from main program. Can anyone help me with the syntax? Please note that still a bit beginner with c++ classes etc. As I need to run the same copy of this program multiple times and don't want to have a same shared class across multiple instances of this program - need to ensure I create a new class in the main body. Also wanted to mention - printvars - is a pre-built function for me and I don't have control over passing any pointer variables to it - just that I can only use global variables in that function.
class gvars
{
public:
int x=0;
int y=0;
gvars() {}
~gvars() {}
};
std::unique_ptr<gvars> *g=NULL; // Must be a pointer to class
//I can't pass any parameters to this function
//Only have control over the body of the program to access global vars
void printvars()
{
std::cout << (*g).x << " " << (*g).y << std::endl;
}
int main()
{
if (g==NULL)
{
g=new gvars(); // This is critical - create a new class here only
}
(*g).x=10;
(*g).y=20;
printvars(); // Expected output : 10 20
delete g;
return 0;
}

Code is good except only line.
Try change
std::unique_ptr<gvars> *g=NULL; // Must be a pointer to class
to
gvars*g=NULL;
Program will create/delete new instance of your class on each run for sure. Also printvars should work fine.

Related

Using a class and functions to keep track of user stats

I am new to C++, and was wondering what I am doing wrong.
I am trying to create a text-based adventure game that keeps track of player stats using an add or remove function. Currently, my function does not add five points to trust and I am trying to get it to.
#include "function.h"
using namespace std;
int main() {
double trust=100;
editPlayer user(100);
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust);
cout << trust;
Here is my function.cpp only using trust as an example:
#include "function.h"
editPlayer::editPlayer(double trust) {
}
void editPlayer::addTrust(double trust){
trust +=5;
}
void editPlayer::removeTrust(double trust){
trust -=5;
}
And here is my function.h:
#include<iostream>
#include<string>
using namespace std;
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
Lets take your addTrust function:
void editPlayer::addTrust(double trust) {
trust += 5;
}
This will modify the local variable trust, and then the function will end. When the function ends, the life-time of the local variable trust also ends, and the modifications you made to it will be lost.
If you truly want to modify the argument, you need to either pass it by reference:
void editPlayer::addTrust(double& trust) {
trust += 5;
}
Or return the new value:
double editPlayer::addTrust(double trust) {
return trust + 5;
}
If you return the new value, you need to assign to it when calling the function:
trust = user.addTrust(trust);
With the above said, the code and the editPlayer class doesn't make much sense. There's just no need for a class editUser really. Possibly addTrust could be a non-member function, or maybe not a function at all.
The class name doesn't make sense, since it doesn't "edit" anything. And passing an argument to the constructor also doesn't make sense since the objects doesn't have any internal state (the value passed to the constructor is just discarded).
Currently you're not storing anything specific on behalf of user object (an object of the editPlayer class.
The cout << trust; statement just prints a value of the trust local variable which you declared at the beginning: double trust=100;. Because this variable hasn't been changed anyhow since that initialization it is still equal to 100 and this is what you see.
In order to track any editPlayer-specific information the best idea is to store that information as a data member of the class editPlayer. You can declare a data member representing the trust of an object like this:
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const; // add also this one, will be useful
private:
double m_trust {0}; // <---- here - a data member, aka. a class field
};
Now you must refine you constructor to let it utilize the parameter which it takes and assign its value to this new data member (because currently the constructor does nothing):
editPlayer::editPlayer(double trust) {
m_trust = trust;
}
Now in the member functions that you already have just rename the variable so that it reflects the trust data member (and not the parameter) which effectively will allow to update its value:
void editPlayer::addTrust(double trust) {
m_trust += 5;
}
void editPlayer::removeTrust(double trust) {
m_trust -= 5;
}
double editPlayer::getTrust() const { // add definition of our "getter"
return m_trust;
}
Finally you can replace that cout << trust; which we already discussed (still prints the local variable's value) with an invokation of the getter which yields m_trust's value:
cout << user.getTrust();
and see the actual effect of performing the addTrust() operation as well as get delighted with your legitimate object-oriented program.
In general the code you are asking can be covered by classes, member declarations and also a pinch of object oriented programming.
The internet has lots of good (and less than good) tutorials if you search for it.
I would try my luck with some of the following searches
CPP + classes
CPP + member declarations
CPP + dynamic vs. static memory allocation (pointers and stuff)
object oriented programming (OOP)
The examples on this site provide good (and short :D) examples of alot of basic concepts imho.
https://www.tutorialspoint.com/cplusplus/cpp_classes_objects.htm
Some of the topics also apply to other languages.
The first block with my comments:
#include "function.h"
using namespace std; // dont get into the habbit of using namespace std;
// the above can potentially open up for bugs
int main()
{
double trust=100; // This variable is declared in this scope({ ... })
// and will get deallocated once the scope ends with the character '}'
editPlayer user(100); // instance of editPlayer named 'user' is constructed
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust); // calling function on user object
cout << trust;
}
Now looking at the .h file i would advocate against including headers that you dont use in the header.
For small projects it does not matter at all - but for big projects of thousands lines of code removing unused includes can speed up things.
Some would prefer forward declarations - which you can look into once you are more comfortable with the basics of cpp.
#include<iostream> // not used here
#include<string> // not used
using namespace std; // disaster waiting to happen
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
The .cpp file
#include "function.h"
editPlayer::editPlayer(double trust) {}
// function implementation with argument - but argument is not used - change to void fun(double) -> fun(void) OR fun()
void editPlayer::addTrust(double trust) { trust +=5; }
void editPlayer::removeTrust(double trust) { trust -=5; }
I did an example with class declaration and member variables.
#include <iostream>
#include <string>
// this is a class declaration
class Player
{
protected: // protected member variables
double _trust;
public: // public interface
Player(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const;
};
// Implementation of public interface
// notice _trust is the member defined in the class
Player::Player(double trust) : _trust(trust) {} // constructor
// example of default parameters (do note that only definition or declaration can have them)
// This means that calling the function without arguments will become 5
void Player::addTrust(double trust = 5) { _trust += trust; }
void Player::removeTrust(double trust = 5) { _trust -= trust; }
double Player::getTrust() const {return _trust; }
int main()
{
Player player(100); // this will invoke the constructor - and the player object will get initialised with the given state
std::cout << player.getTrust() << std::endl;
// variable to buffer input data into - assuming type int wrt. following if
int firstChoice;
//asks user choice
std::cin >> firstChoice;
if (firstChoice == 1)
{
player.addTrust(25);
player.addTrust();
}
std::cout << player.getTrust();
}
Happy coding !

How to change value of an object from a function in c++?

Scenario
I am in the process of learning C++, so please forgive my naivety. I have attempted to build my own class, objects and methods - each of which seem to work as expected. However I am running into issues with what seems to be uninitialized storage (and possibly the use of local objects?) however I would like to know how to fix it, if indeed it is meant to be, or an alternative. My current train of thought is that the object needs to be passed...however that could be way off...
Code
//header
class Car{
public:
USHORT GetMin();
void SetMin(USHORT min);
private:
USHORT itsMinPrice;
};
USHORT Car::GetMin(){
return itsMinPrice;
}
void Car::SetMin(USHORT min){
itsMinPrice = min;
}
-
void StartingPrices(){
Car Mercedes;
std::cout << Mercedes.GetMin() << "\n";
Mercedes.SetMin(50);
std::cout << Mercedes.GetMin()<< "\n";
}
int main(){
float input;
Car Mercedes;
Mercedes.SetMin(100);
StartingPrices();
std::cout << Mercedes.GetMin() << "\n";
std::cin >> input;
return 0;
}
Expected output
100, 50, 50
Actual output
debug win32 - 52428, 50, 100
release win32 - 0, 50, 100
In your StartingPrices function, the Mercedes object you call GetMin is created on the line before, i.e., not the same object as the one you create in the main function.
That means that the object do not yet have itsMinPrice set to anything, hence the value will be garbage (that is, a value which you don't really have control over), in this case 52428 in debug and 0 in release.
What I think you wish to do is pass a reference of the Mercedes object from the main function into the StartingPrices function:
void StartingPrices(Car& mercedes){
std::cout << Mercedes.GetMin() << "\n"; // Here the GetMin method will return 100.
...
}
int main(){
....
Car Mercedes;
Mercedes.SetMin(100);
StartingPrices(Mercedes);
....
}
Its also a good idea to set the default value of the members in the constructor of the class.
In your Car class you do not initialize your member variable itsMinPrice except when you call SetMin, this means there is a risk that you will use an uninitialized Car instance if you forget to call SetMin on it. Normally it is good to have initialization in a constructor of the class with some value e.g.
Car() : itsMinPrice(0) {
}
or create a constructor that takes an initial value
Car(USHORT minValue) : itsMinPrice(minValue) {
}

Why/When would I want to use a class data member without defining an object of the class?

It is possible in C++ to use a data member of a class without defining an object of that class, by defining that data member in the public section as a static variable, as in the code sample below. The question is, why/when would I want to do this? and how can I do it?
class ttime{
public:
ttime(int h=0, int m=0, int s=0):hour(h), minute(m), second(s){} //constructor with default intialization
int& warning(){return hour;}
void display()const{cout<<hour<<"\t";}
static int hello;
~ttime(){}
private:
int hour;
int minute;
int second;
};
main()
{
ttime:: hello=11310; //Is this the way to use hello without creating an object of the class?
cout << ttime:: hello;
ttime hi(9);
hi.display();
hi.warning()++;//the user is able to modify your class's private data, which is really bad! You should not be doing this!
hi.display();
}
Declaring a class member variable as static essentially makes it a singleton object that is shared by all of the instances of that class. This is useful for things like counters, semaphores and locks, and other types of data that need to be shared by the other class members.
Declaring it public makes it accessible to all users of that class. It's generally a bad idea to allow class variables to be modifiable by functions outside the class, though.
Declaring it const, on the other hand, is the usual way to provide publicly readable constants for the class.
Example
Your library class:
class Foo
{
public:
// Version number of this code
static const int VERSION = 1;
private:
// Counts the number of active Foo objects
static int counter = 0;
public:
// Constructor
Foo()
{
counter++; // Bump the instance counter
...
}
// Destructor
~Foo()
{
counter--; // Adjust the counter
...
}
};
Some client of your library:
class Bar
{
public:
// Constructor
Bar()
{
// Check the Foo library version
if (Foo::VERSION > 1)
std::cerr << "Wrong version of class Foo, need version 1";
...
}
};
In this example, VERSION is a static constant of the class, which in this case informs the outside world what version of the code is contained in the class. It's accessed by the syntax Foo::VERSION.
The static counter variable, on the other hand, is private to the class, so only member functions of Foo can access it. In this case, it's being used as a counter for the number of active Foo objects.
As cited before, static member variables work as 'global' variables, but within the class namespace.
So it is useful for counters or shared resources between objects.
In the case of 'public static' modifier, it is easy to see its use within libraries to provide access to constants and general-purpose functionality (static methods).
For example, an input library might have:
class KeyEvent
{
public:
static const int KEY_DOWN = 111;
static const int KEY_UP = 112;
...
}
//And then in your code
#include <KeyEvent>
void poolEvent(Key *key)
{
if(key->type() == KeyEvent::KEY_DOWN)
...
}
I am not familiar with the c++ syntax for statics at the moment. But in c++-cli (.net, Visual C++) the :: is correct.
For the purpose of statics:
There are many cases where it makes sense to use them. In general, when you want to store information that belong to the class itself (meaning to all objects of the class) and not to a single object/instance.
Even though not originally invented for this purpose, static constexpr data members of structs are a backbone of template meta-programming. Just check out the limits standard library header as a simple example.
For example, we can define a wrapper around the builtin sizeof operator. While rather useless in itself, it hopefully gives the right idea.
#include <iostream>
template<typename T>
struct Calipers
{
static constexpr auto size = sizeof(T);
};
int
main()
{
std::cout << "short: " << Calipers<short>::size << "\n";
std::cout << "int: " << Calipers<int>::size << "\n";
std::cout << "long: " << Calipers<long>::size << "\n";
std::cout << "float: " << Calipers<float>::size << "\n";
std::cout << "double: " << Calipers<double>::size << "\n";
}
Possible output:
short: 2
int: 4
long: 8
float: 4
double: 8
It is similar to a global variable, only that it is not defined at the global namespace.
You find it in C++ code that was written before namespaces were introduced, or in template meta programming were it is more useful.
In general, I would not recommend to use it as in your example and would prefer to avoid global state as much as possible. Otherwise, you end up with code that is difficult to test.

How do I point at a vector in another class?

I have a class that holds a vector, which also inherits another class:
class txtExt : public extention
{
private:
string openedFile_;
public:
vector<string> txtVector; //the vector i want to call
};
I fill the vector in a method within a class:
class Manager : public extention
{
// there is some other code here that I know does work
// and it calls this function:
void organizeExtention(string filename, string ext)
{
if(ext == "txt")
{
txtExt txtExt;
txtExt.txtVector.pushback(filename);
}
}
}
and this is my main class where i attempt to call the vector:
int main()
{
// some code here that does previous operations like getting the path
// and filling the vector
// I've tried many ways of trying to call the vector
// here is an example of one:
vector<txtExt*> testVector;
for(int i = 0; i < testVector.size(); ++i)
{
cout << testVector[i] << endl;
}
return 0;
}
I have a few questions:
Am I calling the vector wrong?
Is my vector empty?
Do I have to make my vector global, so other classes can see it?
Note: I've been able to print out the vector where I load the vector using a very simple for loop
Well, as has been said you have a few errors in the code posted, and you maybe have some misunderstandings as well. But to answer the question asked, this
testVector[i]->txtVector
is the way to access the txtVector object that is inside each of your txtExt objects.
If that doesn't work for you then it's because one of the other errors/misunderstandings you have in your code.
To summarize:
reread the first chapters of a good C++ book ( The Definitive C++ Book Guide and List ), then try try to fix your program and deal with each error one at the time.
There are several errors in your code.
First of all, there's no operator << for printing entities of the type txtExt*.
Even object of type txtExt is not printable just like that.
In addition, the testVector you made is empty, so no .size() will be zero, and there's going to be no looping.
Are you really sure that you like to inherit both your classes from 'extension' ?
You can't call a vector, you can access it.
Having a data member (like the vector) public is not a good idea.
Calling a variable by the same name as a class is a very bad idea.
I have trouble guessing what your code should do. Here's a simple example of things you need to understand:
#include <iostream>
#include <vector>
#include <string>
class TxtExt
{
public:
std::vector<std::string> txtVector;
};
int main(){
TxtExt oneTxtExt;
oneTxtExt.txtVector.push_back("hello");
oneTxtExt.txtVector.push_back("world");
for( auto &i : oneTxtExt.txtVector ){
std::cout << i <<std::endl;
}
}
The following code is correct, but has absolutely no effect. You could as well just write {}:
{
TxtExt TxtExt;
TxtExt.txtVector.pushback(filename);
}
You here create a new object, push back to it (btw it is called push_back), but then the object is destroyed at the end of the scope. Also, don't name you objects the same as the class, it becomes really confusing.

C++ syntax/how to declare, fill and access an array within a class

Please forgive me if I asked too big a question. I tried to work it into an example I found in the forum. Though this is for a class, I'm just trying to figure out my homework and my question is centered around this forum question - I'm not asking for magic code to get an A! (actually am taking this class p/fail for personal enrichment.)
....
I have been using the answer to the following question to try to buildup to a better understanding of a homework problem in my C++ class. But I'm getting stuck because there is some basic idea (just one?:-) I think I just don't get. The code I attached to the bottom of this question is me working with this forum sample, but I haven't gotten a sense yet, of how to setup an array that is inside a class. That is part of the assignment.
C++: syntax for accessing member struct from pointer to class
I'm fighting this problem somewhat, because my background is as a structured programmer - the reason I'm taking this class is to work my brain into an oop mode. So sometimes I go off on a track that leads away from oop, without realizing it.
MY QUESTION
I need to be able to instantiate an object of class 'Foo'. That object needs to have an array of 3 kinds of things associated with it. Uh.. I think in this context those things would be called 'Bar'. Those things have attributes 'otherdata' and 'andMoreData'. There is just one piece of data in the object called 'somedata' (Sorry I am mostly using the names of variables from the code I found here).
So I see it like this.
I have an object I instantiated and it is named 'foo' it is of class 'Foo'. It has one ivar called 'somedata' I can assign a value to. Then I want to setup 3 occurances of 'Bar' data. Each of those occurrances will consist of the ivars otherdata and andMoreData. Maybe with default data for each ivar like this
otherdata = 1, andMoreData = 2
I can't figure out how I write a constructor to get the defualt data into my object.
I can't figure out how I access the data within the object for display or changing.
...
I hope I didn't ask too big a question here
....
HERE IS THE CODE I HAVE BEEN TRYING TO REWORK from this forum , hoping that I could build up from this explanation to a good understanding, but I get stuck when I try to create a constructor.
....
/* MY VARIATION ON FOOBAR
Original EXamples found at
https://stackoverflow.com/questions/915106/c-syntax-for-accessing-member-struct-from-pointer-to-class
*/
#include <iostream>
#include <iomanip>
using namespace std;
const int MAX_num = 3;
class Foo{
// I think I have this right, that Bar is the name of the struct
// and 'mybar' is an ivar within the class, with a data type of 'Bar'
//
public:
struct Bar{
int otherdata;
int andMoreData;
}
mybar; // I think I am saying that mybar is an ivar of type Bar
/* Here I tried to move forward with what I wanted to do, but the
compiler thought it was a bad idea
*/
// Here I'm attempting to create a constructor with default data
{ // set default data for mybar
otherdata = 1;
andMoreData = 2;
}
// Here I'm attempting to fill an array 'nmybar' with 3 occurances of my struct
// but I don't know how to say that it's associated with that struct/variable
// actually this seems like the WRONG place to do this, but my teachers example
// does something similar in the .h file (and of course his example works fine, but I
// don't understand it
nmybar[MAX_num]; // this calls mybar() MAX_num times
int somedata;
};
int main(){
// I instantiate class Foo and name my object 'foo'
Foo foo;
// Then I want to refer to the mybar portion of my foo object
// mybar could contain more than one variable itself, in this case
// it doesn't. so I am just referring to the one variable that
// a 'Bar' variable can contain, which is 'otherdata'
// HERE I added a second variable to the struct to make sure I understood how
// to use it , ok that works
foo.mybar.otherdata = 5;
foo.mybar.andMoreData = 6;
cout << foo.mybar.otherdata << endl ;
cout << foo.mybar.andMoreData << endl ;
return 0;
}
/*
Program loaded.
run
[Switching to process 1297]
Running…
5
6
Debugger stopped.
Program exited with status value:0. */
I cleaned up the code a bit and generated an working example.
#include <iostream>
#include <iomanip>
using namespace std;
const int MAX_num = 3;
class Foo
{
public:
struct Bar {
int otherdata;
int andMoreData;
Bar () : otherdata(1), andMoreData(2) { };
};
Bar mybar[MAX_num]; // Array of MAX_num Bar's
int somedata;
};
int main ()
{
Foo foo;
foo.mybar[0].otherdata = 5; // [0] for first element, [1] for second, [2] for third
foo.mybar[0].andMoreData = 6; // don't try to access higher positions, as the array has
// only three elements
cout << foo.mybar[0].otherdata << endl; // 5
cout << foo.mybar[0].andMoreData << endl; // 6
cout << foo.mybar[1].otherdata << endl; // 1
cout << foo.mybar[1].andMoreData << endl; // 2
return 0;
}
But it looks a bit like you don't really know what to do. I suggest you take an c++ tutorial or book (on stackoverflow there are some entries about good beginner-books) to learn c++ from beginning. While it might look more time-consuming at beginning, you will learn much more that way.
You write a constructor for Bar just like you would any constructor. If Bar wasn't inside Foo then it would be something like this:
struct Bar {
Bar();
int otherdata;
int andMoreData;
};
Bar::Bar(): otherdata(1), andMoreData(2) { }
When you put Bar inside of Foo it becomes:
class Foo {
struct Bar {
Bar();
int otherdata;
int andMoreData;
};
};
Foo::Bar::Bar(): otherdata(1), andMoreData(2) { }
Then to give every instance of Foo 3 instances of Bar objects you would do something like:
class Foo {
struct Bar {
Bar();
int otherdata;
int andMoreData;
};
Bar bars[3];
};
Foo::Bar::Bar(): otherdata(1), andMoreData(2) { }
There are other ways you could format this, but the above is the most idiomatic. You will note that the bars variable and the Bar class are both private in the above. It is generally recognized that member-variables should be private within a class (I'm telling you this because you said your purpose is to understand OO better.) It is sometimes acceptable to make the structure (Bar) itself publicly available, but if the struct is just for the class' convenience, then it is better to make it private as well.
const int MAX_num = 3;
class Foo{
public:
struct Bar{
Bar() { // Constructor - initializes a Bar instance
otherdata = 1;
andMoreData = 2;
}
int otherdata;
int andMoreData;
};
Bar mybar; // Separating the Bar type from the mybar variable. Your original syntax is valid, but this is more common
Bar nmybar[MAX_num]; // nmybar is an array of MAX_num Bar's
int somedata;
};
OK, BIG THANKS to people posting I was able to work up a code sample that I understood.
Then I was able to apply the ideas I learned to my class problem.
I am now able to create the kind of class with a struct and an array that I needed! Now I can rework the rest of my homework solution (I got all the bits and pieces for running the machine to work but with only one drink) to accommodate the desired class. Thank you!
Here is my new sample class, with it's real names, etc.
/*
C++ syntax/how to declare, fill and access an array within a class
started off with MacGucky's solution
*/
include
include
using namespace std;
const int UNIQUE_DRINKS = 5;
/*
class DrinkMachine {
private:
string drink ;
double cost;
int drinksLeft;
double moneyCollected;
*/
class DrinkMachine
{
public:
/* So there are TWO members in class 'DrinkMachine'
one is 'moneyCollected'
the other is 'Bottles'
'Bottles' has 3 attributes:
a) 'drink' -name of drink
b) 'cost' - how much for one drink
c) 'drinksLeft' - how many of each unique drink are stocked in the machine
*/
struct Bottles {
string drink;
double cost;
int drinksLeft;
// this is a constructor for 'Bottles' It puts default data into an instance OF 'Bar'
Bottles () : drink("cola"), cost(0.75), drinksLeft(20) { };
};
Bottles myBottles[UNIQUE_DRINKS]; // myBottles is an Array of UNIQUE_DRINKS Bottles
// refer to 'myBottles' like a member, that has children (two dots for it's children)
// versus one dot for moneyCollected
double moneyCollected;
};
int main ()
{
// instantiate DrinkMachine, create an object named 'Building1'
cout << "Lets's fill up the drink machine in Building 1 ! " << endl ;
DrinkMachine Building1;
Building1.moneyCollected = 20.00;
// objectname.ARRAYNAME[position].ivarWithinStruct
// KEEP ALL the defaults for first Bottles item (Cola)
// most of the rest matches the defaults except name and price on water
Building1.myBottles[1].drink = "grape soda";
Building1.myBottles[2].drink = "root bear";
Building1.myBottles[3].drink = "orange soda";
Building1.myBottles[4].drink = "bottled water";
Building1.myBottles[4].cost = 1.00;
for (int i=1; i<=4;i++) {
cout << Building1.myBottles[i].drink ;
cout << " " ;
cout << Building1.myBottles[i].cost ;
cout << " " ;
cout << Building1.myBottles[i].drinksLeft ; //
cout << endl;
}
cout << "\t * * * " << endl ;
cout << "\t Total Bucks Collected Today " << Building1.moneyCollected << endl ;
return 0;
}
/*
Loading program into debugger…
Program loaded.
run
[Switching to process 3332]
Running…
Lets's fill up the drink machine in Building 1 !
grape soda 0.75 20
root bear 0.75 20
orange soda 0.75 20
bottled water 1 20
Total Bucks Collected Today 20
Debugger stopped.
Program exited with status value:0.
*/