The C++ build model is quite different from the Java model. In C++ there are 'declarations' and 'definitions' of various entities, such as functions, classes, methods, etc. C++ source consists of a series of declarations and definitions. Individual modules, or "translation units" are compiled into object code containing whatever entities are defined in that translation unit. Then the compiled translation units making up a program are 'linked' together, where entities defined in one translation unit get hooked up to their usages in other translation units.
In a translation unit, certain uses of entities require only a declaration, while others require full definitions. For example, calling a function only requires the function to be declared. Creating a variable that is a pointer to an object only requires the object's type to be declared. Creating a variable who's type is a class type (rather than a pointer) requires the full definition of the class. What requires a full definition and what only requires a declaration depends on what is required in order to implement the usage. In particular if the usage only needs to know interface details then declarations are enough, but if implementation details are needed then the definition is required.
Additionally, C++ is specified such that the compiler can pretty much be single pass; declarations and definitions must appear in the source code before they are used (for the most part; there are some exceptions) so that C++ will already know what entity is being used when it is mentioned.
So the problem with your code is that when the compiler gets to test()
it doesn't know what test
is. It could be a type or a function or a variable. It doesn't know because it hasn't already been told. You need to tell it, by declaring test
beforehand.
void test();
int main() {
test();
}
Now the compiler will know that test is a function by the time it reaches the attempt to call it. And since calling a function doesn't need to know anything except the function's signature, you could put the definition of test
into a completely different translation unit, if you wanted to. You'd compile both translation units and then the linker would connect the code that calls test()
up to the definition of that function in the other compiled translation unit.
Header files are a common trick in C and C++ that make it easy to have a single source for declarations shared between translations units. They aren't strictly necessary, but if you mess up a declaration by declaring something slightly differently in different files then your program could fail in unexpected and unpredictable ways.
#include
directives simply take whatever file you name and paste the contents into your source code. This way you have a single source for whatever it is you put in the header, such as a function declaration, for example. That way you can ensure that the an identical declaration is included in every file you need it in, without worrying about if maybe you declared something slightly differently in one file from another.
You can also put your class definitions in header files, because a class definition needs to be repeated in every translation unit where that class is used in certain ways. Again, you could write out the needed information manually in every translation unit, but it's easier to stick the definition in a header and let #include
directives do the copying and pasting for you.
If you want to learn C++ I recommend getting a good book. If you weren't already familiar with programming I'd recommend Programming: Principles and Practice Using C++. Since you say you've already programmed then I've heard a better book for you might be Accelerated C++.