Quote:Original post by kmart
1. Why do I need to redeclare cout and cin in every file its used? If I don't the project won't compile saying cout and cin are undeclared identifiers.
I assume you're referring to these lines:
#include <iostream>using std::cout;using std::cin;
You're not
declaring[ cin and cout. The 'using' lines simply add std::cout and std::cin into the global namespace. If you didn't have these lines, you could still use cout by using its qualified name, std::cout.
I don't think Java has namespaces yet, so you may not be familiar with them, but put simply, they allow you to define your classes, global variables and functions in different scopes. All of the standard library is defined in the std namespace, which means that to use it, you have to prefix with std::.
This is done to avoid naming collisions.
You can create a variable called 'max' without conflicting with the standard library's std::max function, because it's in a separate namespace.
using std::cout; simply tells the compiler to take cout from the std namespace, and add it to the current namespace, so that in the future, if it sees 'cout' used in this namespace, it actually means std::cout.
But std::cout always existed, so you're not
declaring anything. It's not a new variable or anything.
Second, why do you have to do this in every file? Because that's how C++ works. Every .cpp file is compiled independently. The compiler reads
one .cpp file, expands all the #includes, evaluates the macros, and ends up with one translation unit which is compiled to one .obj file.
This means that each of these have to make sense in isolation. One .cpp file can't see variables or types defined in another. Hence you need to #include things again, and if you're pulling std::cout into the global namespace, you have to do that in every file as well.
If you define a class, that too must be declared in every .cpp file that uses it (possibly just by including a common header).
This allows the compiler to see that "somewhere, this type exists. I don't know what happens when you call the member functions, but I know they exist, and I know their signatures, so I can generate code to call them".
So when the compiler has run, you're left with a handful of .obj files.
They are passed to the linker, which solves all these dangling references to types that were unknown during compilation. It merges them all together, checks that all these links between compilation units could be resolved, and generates your .exe.
Quote:
2. In newCharacter.hpp I can't declare the variables isCharacterRunning and characterChoice. If I do the project errors saying they are already defined in main.obj. This forced me to create variables inside the cpp and pass them through the function.
This ties in to what I said above as well. Each .cpp file is compiled in isolation. Now, what happens if multiple .cpp files include newCharacter.hpp?
They each see the lines
bool isCharacterRunning;int characterChoice;
and so they create the two variables.
And what happens when the linker merges the two .obj files together? It finds two conflicting definitions of the variables. They have the same names, and are located in the same namespace. What does it do then? How does it know which of the two variables you're referring to?
The solution (if you want to use global variables) is to define the variables in a single .cpp file, and then put 'extern bool isCharacterRunning;' in a header file that all the .cpp files can see.
This way, one .cpp file, and only one, sees the declaration of the variables, and puts them into its .obj file.
All the others only see the 'extern' lines, which essentially mean "this variables will be declared elsewhere, in another .cpp file, but it'll look like this, so you can refer to it if you like".
All the .cpp files should now compile, and when sent to the linker, it sees
one declaration of the two variables, and a lot of references to them. And it can handle that. The variable is created in one place only, and everyone else are merely using it.
That said, your current solution is probably better. Globals should generally be avoided.