Anatomy of a C++ file
C++ is a powerful, high-performance, compiled programming language that supports procedural, object-oriented, and generic programming.
File extensions: .cpp, .hpp
Every part of the example below is labelled and explained. This page is one of 55 annotated tours on AnatomyOf, a free, open-source project by LunarWerx Studios.
What is inside a C++ file
Comment
Block (/* ... */) or single-line (//), ignored by the compiler.
A /* ... */ block comment can span multiple lines but does not nest, so the compiler stops at the first */ it finds. // single-line comments run to the end of the physical line and are the more common style in modern C++ for short, local notes. Both forms are removed during translation before the compiler ever sees C++ syntax proper, so they have zero effect on the generated machine code. Because C++ offers no built-in doc-comment format, tools like Doxygen instead scan specially formatted //! or /** */ comments to generate reference documentation.
Preprocessor directive
Processed before compilation (starts with #).
#include <iostream> runs through the preprocessor, a text-substitution pass that copy-pastes the named header's declarations into the file before the compiler proper runs. Angle brackets search the standard/system include paths; quotes search the local project directory first. C++ inherits the preprocessor from C, but modern C++ leans on it far less: templates, constexpr, and (since C++20) modules replace many of the macro tricks C code relies on. Headers like <iostream> and <string> pull in the standard library facilities used throughout this file.
Using directive
Makes names from a namespace available without qualification.
The entire standard library lives inside the std namespace, so cout is really std::cout. using namespace std; imports every name from std into the current scope, letting the rest of the file write cout and string instead of spelling out the prefix each time. It is convenient for short programs and teaching examples, but real-world C++ code and header files generally avoid a blanket using namespace std; because it can silently introduce naming collisions as the standard library grows; a targeted using std::cout; or an explicit std:: prefix is the safer habit.
Class definition
The blueprint for objects (class ...).
class Greeter { ... }; defines a new type: a bundle of data (member variables) and behavior (member functions) that objects of that type will share. Note the semicolon after the closing brace: unlike a function body, a class definition is a declaration and must be terminated. Classes are the foundation of object-oriented C++ and also enable RAII (Resource Acquisition Is Initialization): a constructor acquires a resource and the destructor releases it automatically when the object goes out of scope, which is how C++ manages memory and handles without a garbage collector.
Access specifier
Controls visibility (public, private, protected).
private: and public: are labels, not blocks. Every member declared after one applies until the next specifier appears. Private members are only reachable from inside the class's own member functions; public members form the class's external interface that other code is allowed to call. A third specifier, protected, behaves like private but also stays visible to derived classes. Classes default to private access when no specifier is given (the struct keyword defines the same kind of type but defaults to public), so Greeter states private: explicitly for its data.
Member variable (field)
Data stored within an object.
string greeting; declares a per-object field: every Greeter instance gets its own independent copy of greeting. Because it sits under private:, only Greeter's own member functions can read or write it directly. Outside code must go through a public method. Member variables are typically initialized in the constructor, as greeting is here via the constructor's parameter. Modern C++ also allows default member initializers written directly at the declaration (e.g. string greeting = "Hi";), which apply whenever a constructor does not override them.
Constructor
Special method to initialize an object.
A constructor shares its name with the class and has no return type. Greeter(string g) { greeting = g; } runs automatically whenever a Greeter is created, giving the new object a chance to set up its member variables before any other code can touch it. Constructors can be overloaded (multiple constructors with different parameter lists), and C++11 added member initializer lists (Greeter(string g) : greeting(g) {}) as the preferred way to initialize fields, since they initialize directly rather than assigning after default construction.
Member method
A function defined within a class.
void greet(string name) { ... } is a function that belongs to Greeter and can freely read the object's own member variables, here it reaches greeting without needing it passed in as a parameter. Every non-static member function implicitly receives a pointer to the calling object, accessible explicitly as this. Member functions can be marked const to promise they will not modify the object, virtual to allow derived classes to override them, or static to belong to the class itself rather than any particular instance.
Main function
The entry point for a C++ application (int main()...).
Every standalone C++ program has exactly one main function, and execution begins there. Its int return type is the process's exit status handed back to the operating system: 0 conventionally means success, and any nonzero value signals an error. main may also be written to accept command-line arguments as int main(int argc, char* argv[]). Reaching the closing brace without an explicit return is a special case C++ allows only for main, implicitly returning 0.
Local variable
A variable declared inside a function.
string userName = "World"; declares a variable scoped to the block it appears in: here, the body of main. It is constructed when execution reaches the declaration and destroyed automatically when that scope ends, which for a std::string means its destructor frees any heap memory it allocated. C++ favors this kind of automatic, stack-managed lifetime (RAII) over manual allocation: because the object's destructor runs deterministically at scope exit, resources are released without needing a garbage collector or explicit free.
Object instantiation
Creating an instance of a class.
Greeter myGreeter("Hello"); constructs a new Greeter object on the stack, passing "Hello" to its constructor, which stores it as greeting. No new keyword is needed here because the object's lifetime is tied to the enclosing scope rather than the heap. Heap allocation is still available via new Greeter("Hello"), which returns a pointer and requires an explicit delete (or, in modern C++, a smart pointer like std::unique_ptr that deletes automatically). Stack construction like this example is preferred whenever the object does not need to outlive its scope.
Method call
Executing a method on an object.
myGreeter.greet(userName); invokes the greet member function on the specific object myGreeter, using the dot operator. Inside greet, this implicitly refers back to myGreeter, which is how the method can reach its own greeting field. The dot operator (.) is used for objects and references; when calling a method through a pointer to an object, C++ uses the arrow operator (->) instead, which is shorthand for dereferencing the pointer and then applying ..
Console output
Writing to standard out (cout with <<).
cout is the standard output stream declared in <iostream>, and << is the stream insertion operator: cout << greeting << ", " << name << "!" << endl; chains several values onto the stream in sequence. Because << is overloaded for every built-in type and for std::string, the same syntax works whether you are printing numbers, text, or custom types that define their own overload. endl writes a newline and flushes the stream's buffer; "\n" also writes a newline but without the forced flush, so it is typically cheaper in output-heavy code. The matching input stream, cin, reads from standard input u
Control flow (conditional)
Executes code based on a condition (if, else, switch).
if (userName == "World") { ... } runs its block only when the parenthesized expression evaluates to true. std::string overloads == to compare contents rather than pointer identity, so this compares the actual characters rather than memory addresses. else and else if chain additional branches, and switch dispatches on an integral or enum value across case labels. Since C++17, if can also carry an init-statement (if (auto it = find(...); it != end)), scoping a helper variable to the condition and its branches.
Official C++ site · All languages on AnatomyOf
The interactive tour needs JavaScript. Enable it to hover a callout and trace it into the code.