[Solved]Defining Variables at start of Main-File in C++
So it is a very bad idea to allocate variables like that. Once the project gets to any decent size it will be unmanageable. Again if multiple cpp files call header files that require the coffee variable then it is sometimes just luck of the draw which gets compiled first, meaning it might compile, but it might not.
So there is a few things I will comment on now I can see your header file, some of it is my opinion of best practices (to each their own) and others are still my opinion of best practices but you really should be following these ones.
Well lets get to the light-hearted practices. In C++ you can actually declare public once and you don't have to keep doing it (example below all bundled together). Another practice, which I even break, is keeping function implementations out of the header file. Usually you create a separate cpp file which contains the implementations (named the same). This also has the benefit that you can shove things like variables into the cpp file, without using them in the header file (as it is all self contained in the cpp file). Although in this case you should probably make it a class variable (I will show both ways in the example).
One last little practice would be to define the variable in the cpp file, and not in the main function (This isn't always the case, there are times where you want to initialize at certain stages, but in this case you could do it prior to main being called).
*In general the header should only be including what is needed to compile and understand the class you are making, nothing more*
So now for practices you should be following (some aren't even opinions, some are you must follow if you want the project to grow anymore in size).
So header guards, header guards are protections put in header files to prevent them from being included more than once (and causing issues). I will show them in the example and point them out, but you really need to be using them (Also called include guards...there is even a wiki article about it)
The next issue is the using namespace std; in your header. Using namespace in any header file is frowned upon. By calling using namespace you are actually making it so any following cpp files that call the header will also use that namespace. This can cause undesired consequences later on (if someone using the header file without realizing namespace was called, or if there was a conflict in names)
So here is my suggestion of what your code should look like after the changes (although it isn't really fully correct as I wanted to give examples of different ways). Excuse any errors I did this in notepad without a compiler, and I haven't been keeping up with C++ as much as I would like
Items.h
#ifndef _ITEMS_H_#define _ITEMS_H_ //So the above is an header guard. It will prevent the compiler from compiling the header more than once. This is very important to have in ALL header files//just change the name of the guard...eg. _MYHEADER_H_class Items {public: //Notice only defining it public once...everything following this virtual void take() = 0; virtual void drop() = 0; virtual void drink() = 0; virtual void eat() = 0;//So there is a design choice which I am not mentioning because I don't really have the time to discuss it and I think it is a bit much given everything else//I am trying to put across...in short though instead of the counter being in coffee if you move it to here. Then you don't have to keep creating new variables//to do the same thing...but this requires a bit more initial work (if you had 5+ different items it would be worth while looking into this) I will explain this//in another post when I get more time and have the energy};class Coffee : public Items {public: void take(); //These will be defined in the items.cpp file void drop(); public: void drink(); //You can still define it with public: like this but I personally like it without, looks cleaner void eat(); Coffee(): currentCoffeeCount(0) {}; //So this is the only implementation I personally usually do. This is because it is very short //if I needed to do work in it though I would move it into items.cpp. As another note, notice I am initializing the currentCoffeCount variable //here. static int getTotalCoffees() { return currentCoffeeCount; }; //Okay so I lied, I do getters in here too I added this to show later on int currentCoffeeCount; //I renamed this because I needed more variables to show different approachesprivate: static int totalCoffees; //This is a new variable, notice it is private so only the class coffee will be able to access this variable //The above variable is quite different from currentCoffeeCount. First only Coffee can access it, the next is the static will mean //that there will only be one of it. This means it tracks multiple coffee objects for their totals //Notice that this variable has to be initialized in items.cpp it can't be initialized in the header, or even in a function it has to be //in a cpp file};//Need to close the guard#endif
Items.cpp
//Items.cpp#include "Items.h"using namespace std; //It is safe here, because this namespace won't be able to spread as it is a cpp fileint Coffee::totalCoffees = 0; //This is where totalCoffees is initialized. So you don't have to worry about it in any other cpp files//Sorry if any syntax is wrong, I haven't been doing C++ very much in the last year//This is the implementation of the Items definitionsvoid Coffee::take() { cout << "Coffee taken" << endl; currentCoffeeCount++; totalCoffees++;}void Coffee::drop() { cout << "Coffee dropped" << endl; currentCoffeeCount--; totalCoffees--;}void drink() { cout << "Coffee drunk" << endl; currentCoffeeCount--; totalCoffees--;}void Coffee::eat() { cout << "You can't eat coffee!" << endl; //You obviously never have frozen a coffee in the freezer before}
Main.cpp
//Main.cpp#include "items.h"//The items.cpp handles all the initializations, so all I need to do to use the items class is call the include :)using namespace std;void displayStats(const Coffee &coffee); //Sorry I just like having main initialized first, there is nothing wrong with that you did though//Although I did need to pass the coffee through as it contains the counts :pint main() { Coffee coffeeDispensor1; Coffee coffeeDispensor2; //Creating two to make coffeeDispensor1.take(); //This is so much easier to call than your other methods coffeeDispensor1.take(); coffeeDispensor1.take(); coffeeDispensor1.drink(); coffeeDispensor1.drop(); //1 coffee coffeeDispensor2.take(); //This is so much easier to call than your other methods coffeeDispensor2.take(); coffeeDispensor2.take(); coffeeDispensor1.drop(); //2 coffees for this one, but there is a total of 3 coffees out there system("CLS"); //Clearing screen here displayStats(coffeeDispensor1); displayStats(coffeeDispensor2); //ANd printing out the global amount cout << "Total cups of coffee:\t\t" << Coffee.getTotalCoffees() << "\n"<<endl;}void displayStats(const Coffee &coffee) { cout << "Cups of coffee:\t\t" << coffee.currentCoffeeCount << "\n"<<endl;}
There are more design choices that I could talk about, but for now I will leave it at this. (I don't want to flood with too much information)
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now