From Absolute Beginner to Professional Programmer


Table of Contents

  1. Introduction to C++
  2. Installing and Using Dev-C++
  3. Your First C++ Program
  4. Program Structure
  5. Comments
  6. Variables
  7. Data Types
  8. Constants
  9. Output
  10. Input
  11. Operators
  12. Conditional Statements
  13. Loops
  14. Functions
  15. Arrays
  16. Strings
  17. Pointers
  18. References
  19. Structures
  20. Enumerations
  21. Object-Oriented Programming
  22. Classes and Objects
  23. Constructors and Destructors
  24. Encapsulation
  25. Inheritance
  26. Polymorphism
  27. Abstraction
  28. Operator Overloading
  29. Static Members
  30. Namespaces
  31. Header Files
  32. Multiple Source Files
  33. The Standard Library
  34. Vectors
  35. Maps
  36. Sets
  37. Iterators
  38. Algorithms
  39. Lambda Functions
  40. Templates
  41. Exception Handling
  42. File Handling
  43. Dynamic Memory
  44. Smart Pointers
  45. RAII
  46. Move Semantics
  47. Modern C++
  48. Date and Time
  49. Random Numbers
  50. Debugging
  51. C++ Project Organization
  52. Building Larger Programs
  53. CMake and Professional Development
  54. Testing
  55. Git
  56. Multithreading
  57. Performance
  58. Security
  59. Professional C++ Practices
  60. Projects
  61. Rapid-Learning Roadmap
  62. Final Professional Project

1. Introduction to C++

C++ is a general-purpose programming language designed for both high-level software development and low-level system control.

It is used for:

  • Operating systems
  • Game engines
  • Desktop applications
  • Embedded systems
  • Robotics
  • Compilers
  • Databases
  • Financial systems
  • Networking
  • Scientific computing
  • High-performance applications

C++ gives you considerable control over memory and hardware while still providing powerful abstractions.

Why learn C++?

C++ teaches concepts that transfer to many other languages:

  • Data types
  • Algorithms
  • Memory
  • Data structures
  • Object-oriented programming
  • Compilation
  • Software architecture
  • Performance
  • Concurrency

If you understand C++ deeply, many other programming languages become easier to understand.


2. Using Dev-C++

Dev-C++ is an integrated development environment, or IDE, that allows you to write, compile, run and debug C++ programs.

A typical workflow is:

Write code
   ↓
Save .cpp file
   ↓
Compile
   ↓
Fix errors
   ↓
Run
   ↓
Test
   ↓
Improve

Your C++ source files normally use:

.cpp

For example:

main.cpp
calculator.cpp
student.cpp

Creating a project

In Dev-C++:

File
→ New
→ Project
→ Console Application
→ C++

Give the project a name.

Dev-C++ will create a project structure for you.

For very small programs, you can also create a source file directly.


3. Your First C++ Program

Create a C++ source file containing:

#include <iostream>

int main()
{
    std::cout << "Hello, World!";

    return 0;
}

Compile and run it.

You should see:

Hello, World!

Congratulations.

You have written your first C++ program.


4. Understanding the Program

Consider:

#include <iostream>

This includes functionality for input and output.

int main()

This is the main function.

Execution begins here.

std::cout

means standard output.

<<

sends data to the output stream.

return 0;

indicates successful program termination.

The braces:

{
}

define a block of code.


5. Semicolons

Most C++ statements end with:

;

Example:

int age = 20;
std::cout << age;

Forgetting the semicolon is a common beginner error.


6. Comments

Single-line comments:

// This is a comment

Multiple-line comments:

/*
   This is a
   multiline comment.
*/

Comments are ignored by the compiler.

Use them to explain code where necessary.


7. Variables

A variable stores information.

int age = 20;

This contains:

int       → type
age       → name
20        → value

Example:

#include <iostream>

int main()
{
    int age = 20;

    std::cout << age;

    return 0;
}

You can change a variable:

int age = 20;

age = 21;

8. Naming Variables

Good:

studentAge
firstName
totalPrice
accountBalance

Bad:

x
a1
something

unless the short name has an obvious mathematical or local meaning.

C++ is case-sensitive:

age

and:

Age

are different variables.


9. Data Types

Integer

int age = 20;

Stores whole numbers.

Examples:

-10
0
25
1000

Floating-point

float price = 19.99f;

and:

double salary = 5000.50;

double is normally preferred for general floating-point calculations.


Character

char grade = 'A';

Characters use single quotes.


Boolean

bool loggedIn = true;

Possible values:

true
false

String

#include <string>

std::string name = "Mihigo";

Strings use double quotes.


10. Common Data Types

Type Example
int 25
float 2.5f
double 2.5
char 'A'
bool true
std::string "Hello"

There are also:

short
long
long long
unsigned

Use them when their specific ranges or properties are appropriate.


11. Constants

A constant cannot normally be modified.

const double PI = 3.14159265359;

Attempting:

PI = 4;

will cause an error.

Constants are useful for:

const int MAX_STUDENTS = 100;
const double TAX_RATE = 0.18;

12. Output

Use:

std::cout

Example:

std::cout << "Hello";

Multiple values:

std::string name = "Mihigo";
int age = 20;

std::cout << "Name: " << name << "\n";
std::cout << "Age: " << age << "\n";

\n means newline.

You can also use:

std::endl

but \n is commonly preferred when you simply need a new line.


13. Input

Use:

std::cin

Example:

int age;

std::cout << "Enter your age: ";
std::cin >> age;

std::cout << "You are " << age << " years old.";

Multiple variables:

int age;
double height;

std::cin >> age >> height;

14. Reading Strings

For one word:

std::string name;

std::cin >> name;

For a complete line:

std::getline(std::cin, name);

Example:

#include <iostream>
#include <string>

int main()
{
    std::string name;

    std::cout << "Enter your full name: ";
    std::getline(std::cin, name);

    std::cout << "Hello " << name;

    return 0;
}

15. Arithmetic Operators

C++ provides:

+    addition
-    subtraction
*    multiplication
/    division
%    remainder

Example:

int a = 10;
int b = 3;

std::cout << a + b << "\n";
std::cout << a - b << "\n";
std::cout << a * b << "\n";
std::cout << a / b << "\n";
std::cout << a % b << "\n";

Integer division:

10 / 3

produces:

3

For decimal division:

10.0 / 3.0

produces approximately:

3.33333

16. Assignment Operators

Basic:

x = 10;

Compound:

x += 5;
x -= 5;
x *= 5;
x /= 5;
x %= 5;

Increment:

x++;

Decrement:

x--;

17. Comparison Operators

==    equal
!=    not equal
>     greater
<     less
>=    greater or equal
<=    less or equal

Example:

int age = 20;

if (age >= 18)
{
    std::cout << "Adult";
}

Be careful:

=

means assignment.

Whereas:

==

means comparison.


18. Logical Operators

AND:

&&

OR:

||

NOT:

!

Example:

if (age >= 18 && hasID)
{
    std::cout << "Access granted";
}

19. if

if (condition)
{
    // code
}

Example:

if (age >= 18)
{
    std::cout << "You are an adult.";
}

20. if...else

if (age >= 18)
{
    std::cout << "Adult";
}
else
{
    std::cout << "Minor";
}

21. else if

if (score >= 80)
{
    std::cout << "Excellent";
}
else if (score >= 60)
{
    std::cout << "Good";
}
else if (score >= 50)
{
    std::cout << "Pass";
}
else
{
    std::cout << "Fail";
}

22. Nested Conditions

You can place conditions inside conditions.

if (age >= 18)
{
    if (hasID)
    {
        std::cout << "Access granted";
    }
}

Don't overuse nesting. Complicated conditions should often be extracted into functions or variables.


23. The Ternary Operator

Instead of:

if (age >= 18)
{
    status = "Adult";
}
else
{
    status = "Minor";
}

you can write:

std::string status =
    age >= 18 ? "Adult" : "Minor";

Use this for simple expressions.


24. switch

Useful when a single value has several possible cases.

int choice;

std::cout << "1. Add\n";
std::cout << "2. Edit\n";
std::cout << "3. Delete\n";

std::cin >> choice;

switch (choice)
{
    case 1:
        std::cout << "Add selected";
        break;

    case 2:
        std::cout << "Edit selected";
        break;

    case 3:
        std::cout << "Delete selected";
        break;

    default:
        std::cout << "Invalid choice";
}

25. Loops

Loops repeat code.

while

int i = 1;

while (i <= 5)
{
    std::cout << i << "\n";
    i++;
}

26. do...while

int i = 1;

do
{
    std::cout << i << "\n";
    i++;
}
while (i <= 5);

The body executes at least once.


27. for

for (int i = 1; i <= 5; i++)
{
    std::cout << i << "\n";
}

A for loop contains:

initialization
condition
update

28. break

Stops a loop.

for (int i = 1; i <= 10; i++)
{
    if (i == 5)
        break;

    std::cout << i << "\n";
}

29. continue

Skips the current iteration.

for (int i = 1; i <= 5; i++)
{
    if (i == 3)
        continue;

    std::cout << i << "\n";
}

30. Functions

Functions divide a program into reusable units.

void greet()
{
    std::cout << "Hello!";
}

Call:

greet();

Complete example:

#include <iostream>

void greet()
{
    std::cout << "Hello!\n";
}

int main()
{
    greet();
    greet();
    return 0;
}

31. Function Parameters

void greet(std::string name)
{
    std::cout << "Hello " << name;
}

Call:

greet("Mihigo");

Multiple parameters:

int add(int a, int b)
{
    return a + b;
}

32. Return Values

int add(int a, int b)
{
    return a + b;
}

Use:

int result = add(10, 20);

std::cout << result;

A function returning nothing uses:

void

33. Function Prototypes

You can declare a function before defining it.

int add(int a, int b);

int main()
{
    std::cout << add(10, 20);
    return 0;
}

int add(int a, int b)
{
    return a + b;
}

This becomes important when working with multiple files.


34. Function Overloading

You can create functions with the same name but different parameters.

int add(int a, int b)
{
    return a + b;
}

double add(double a, double b)
{
    return a + b;
}

The compiler determines which function to use based on the arguments.


35. Arrays

An array stores multiple values of the same type.

int numbers[5] = {10, 20, 30, 40, 50};

Indexes begin at zero:

numbers[0] → 10
numbers[1] → 20
numbers[2] → 30
numbers[3] → 40
numbers[4] → 50

Loop:

for (int i = 0; i < 5; i++)
{
    std::cout << numbers[i] << "\n";
}

36. Two-Dimensional Arrays

int matrix[2][3] =
{
    {1, 2, 3},
    {4, 5, 6}
};

Access:

std::cout << matrix[0][1];

Output:

2

37. Strings

#include <string>

std::string name = "Mihigo";

Length:

name.length();

Character:

name[0];

Concatenation:

std::string fullName =
    firstName + " " + lastName;

Searching:

if (name.find("hi") != std::string::npos)
{
    std::cout << "Found";
}

38. References

A reference is another name for an existing variable.

int age = 20;

int& reference = age;

Now:

reference = 30;

also changes:

age

to:

30

References are particularly useful when passing objects to functions.


39. Pass by Value

void increase(int number)
{
    number++;
}

The original variable isn't changed.


40. Pass by Reference

void increase(int& number)
{
    number++;
}

Now:

int age = 20;

increase(age);

results in:

age = 21

41. const References

A common professional pattern is:

void print(const std::string& text)
{
    std::cout << text;
}

This avoids copying the string while preventing the function from modifying it.

This pattern is extremely important in C++.


42. Pointers

A pointer stores an address.

int age = 20;

int* pointer = &age;

&age means:

address of age

Dereference:

std::cout << *pointer;

Output:

20

43. Modifying Through a Pointer

int age = 20;

int* pointer = &age;

*pointer = 30;

Now:

age = 30

44. nullptr

Use:

int* pointer = nullptr;

instead of old-style:

NULL

Check before dereferencing:

if (pointer != nullptr)
{
    std::cout << *pointer;
}

Never dereference a null pointer.


45. Structures

A structure combines related data.

struct Student
{
    std::string name;
    int age;
    double average;
};

Create:

Student student;

student.name = "Mihigo";
student.age = 20;
student.average = 85.5;

Or:

Student student =
{
    "Mihigo",
    20,
    85.5
};

46. Enumerations

Use enum class for strongly scoped enumerations.

enum class Status
{
    Pending,
    Approved,
    Rejected
};

Use:

Status status = Status::Approved;

47. Classes and Objects

A class defines the structure and behavior of objects.

class Person
{
public:
    std::string name;
    int age;

    void introduce()
    {
        std::cout << "I am "
                  << name;
    }
};

Create:

Person person;

person.name = "Mihigo";
person.age = 20;

person.introduce();

48. Constructors

A constructor runs when an object is created.

class Person
{
public:
    std::string name;
    int age;

    Person(std::string n, int a)
        : name(n), age(a)
    {
    }
};

Create:

Person person("Mihigo", 20);

49. Private Members

Use encapsulation:

class BankAccount
{
private:
    double balance;

public:
    BankAccount(double initialBalance)
        : balance(initialBalance)
    {
    }

    void deposit(double amount)
    {
        balance += amount;
    }

    double getBalance() const
    {
        return balance;
    }
};

External code cannot directly modify:

balance

50. Getters and Setters

Getter:

double getBalance() const
{
    return balance;
}

Setter:

void setBalance(double value)
{
    balance = value;
}

Don't create setters automatically for everything. A well-designed class should control its own state.


51. Destructors

A destructor runs when an object is destroyed.

class Test
{
public:
    ~Test()
    {
        std::cout << "Destroyed";
    }
};

Modern C++ often lets the compiler generate destructors automatically.

You should write your own destructor primarily when your class has a specific resource-management responsibility.


52. Inheritance

class Animal
{
public:
    void eat()
    {
        std::cout << "Eating";
    }
};

class Dog : public Animal
{
public:
    void bark()
    {
        std::cout << "Barking";
    }
};

Now:

Dog dog;

dog.eat();
dog.bark();

53. Polymorphism

Base class:

class Animal
{
public:
    virtual void speak() const
    {
        std::cout << "Animal sound";
    }

    virtual ~Animal() = default;
};

Derived:

class Dog : public Animal
{
public:
    void speak() const override
    {
        std::cout << "Woof";
    }
};

Then:

Animal* animal = new Dog();

animal->speak();

delete animal;

For modern code, prefer a smart pointer:

std::unique_ptr<Animal> animal =
    std::make_unique<Dog>();

animal->speak();

54. Abstract Classes

A pure virtual function:

virtual void draw() = 0;

makes the class abstract.

Example:

class Shape
{
public:
    virtual double area() const = 0;

    virtual ~Shape() = default;
};

Derived classes must implement area().


55. Composition

Instead of always using inheritance, objects can contain other objects.

class Engine
{
public:
    void start()
    {
        std::cout << "Engine started";
    }
};

class Car
{
private:
    Engine engine;

public:
    void start()
    {
        engine.start();
    }
};

This is composition.

Professional C++ uses both composition and inheritance, choosing between them based on the design.


56. Operator Overloading

You can define operators for your own classes.

class Point
{
public:
    int x;
    int y;

    Point operator+(const Point& other) const
    {
        return
        {
            x + other.x,
            y + other.y
        };
    }
};

Then:

Point a{10, 20};
Point b{5, 3};

Point c = a + b;

57. Static Members

A static member belongs to the class rather than a particular object.

class Counter
{
public:
    static int count;

    Counter()
    {
        count++;
    }
};

int Counter::count = 0;

58. Namespaces

Namespaces prevent naming conflicts.

namespace Math
{
    int add(int a, int b)
    {
        return a + b;
    }
}

Use:

Math::add(10, 20);

The C++ Standard Library uses:

std::

Therefore:

std::cout
std::string
std::vector

59. The Standard Library

Professional C++ programmers rely heavily on the Standard Library.

Important components include:

string
vector
array
map
unordered_map
set
unordered_set
stack
queue
deque
algorithm
memory
fstream
filesystem
chrono
thread
mutex
optional
variant
tuple

Don't reinvent functionality that the Standard Library already provides.


60. std::vector

A vector is a dynamically sized array.

#include <vector>

std::vector<int> numbers;

numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);

Loop:

for (int number : numbers)
{
    std::cout << number << "\n";
}

Size:

numbers.size();

Remove the last item:

numbers.pop_back();

61. Range-Based Loops

Instead of:

for (size_t i = 0; i < numbers.size(); i++)
{
    std::cout << numbers[i];
}

use:

for (int number : numbers)
{
    std::cout << number;
}

If you don't want to modify the elements:

for (const int& number : numbers)
{
    std::cout << number;
}

62. std::array

For fixed-size collections:

#include <array>

std::array<int, 5> numbers =
{
    10, 20, 30, 40, 50
};

Size:

numbers.size();

63. std::map

A map stores key-value pairs.

#include <map>

std::map<std::string, int> ages;

ages["Mihigo"] = 20;
ages["John"] = 25;

Retrieve:

std::cout << ages["Mihigo"];

Loop:

for (const auto& item : ages)
{
    std::cout << item.first
              << ": "
              << item.second
              << "\n";
}

64. std::unordered_map

std::unordered_map<std::string, int> ages;

This is hash-table based.

It is useful when you don't need keys ordered.


65. Sets

A set stores unique values.

std::set<int> numbers;

numbers.insert(10);
numbers.insert(20);
numbers.insert(10);

Only one 10 exists.


66. Stack

A stack follows:

Last In, First Out

Example:

std::stack<int> stack;

stack.push(10);
stack.push(20);

std::cout << stack.top();

stack.pop();

67. Queue

A queue follows:

First In, First Out

Example:

std::queue<int> queue;

queue.push(10);
queue.push(20);

std::cout << queue.front();

queue.pop();

68. Iterators

Iterators allow algorithms to operate on containers.

auto iterator = numbers.begin();

std::cout << *iterator;

End:

numbers.end();

You normally won't need to write complex iterator code immediately, but understanding iterators is essential for mastering the STL.


69. Algorithms

Include:

#include <algorithm>

Sort:

std::sort(
    numbers.begin(),
    numbers.end()
);

Reverse:

std::reverse(
    numbers.begin(),
    numbers.end()
);

Find:

auto result = std::find(
    numbers.begin(),
    numbers.end(),
    20
);

Count:

int count = std::count(
    numbers.begin(),
    numbers.end(),
    10
);

70. Lambda Functions

A lambda is an anonymous function.

auto greet = []()
{
    std::cout << "Hello";
};

greet();

With parameters:

auto add = [](int a, int b)
{
    return a + b;
};

Use:

std::cout << add(10, 20);

With algorithms:

std::sort(
    numbers.begin(),
    numbers.end(),
    [](int a, int b)
    {
        return a > b;
    }
);

71. auto

C++ can infer a variable's type.

auto age = 20;

The compiler determines:

int

Another example:

auto name = std::string("Mihigo");

auto is particularly useful with complicated types.

Use it when it improves readability, not simply because it is available.


72. Templates

Templates enable generic programming.

template <typename T>
T maximum(T a, T b)
{
    return a > b ? a : b;
}

Use:

std::cout << maximum(10, 20);
std::cout << maximum(4.5, 2.1);

The same function works with multiple compatible types.


73. Template Classes

template <typename T>
class Box
{
private:
    T value;

public:
    Box(T value)
        : value(value)
    {
    }

    T getValue() const
    {
        return value;
    }
};

Use:

Box<int> number(100);

Box<std::string> text("Hello");

Templates are fundamental to the STL.


74. Exception Handling

Use exceptions for exceptional conditions.

try
{
    throw std::runtime_error(
        "Something went wrong"
    );
}
catch (const std::exception& error)
{
    std::cout << error.what();
}

Example:

double divide(double a, double b)
{
    if (b == 0)
    {
        throw std::invalid_argument(
            "Cannot divide by zero"
        );
    }

    return a / b;
}

75. File Handling

Include:

#include <fstream>

Writing

std::ofstream file("data.txt");

file << "Hello\n";
file << "C++";

Reading

std::ifstream file("data.txt");

std::string line;

while (std::getline(file, line))
{
    std::cout << line << "\n";
}

Always consider whether opening the file succeeded:

if (!file)
{
    std::cout << "Could not open file.";
}

76. Append to a File

std::ofstream file(
    "data.txt",
    std::ios::app
);

file << "New entry\n";

std::ios::app adds data rather than replacing existing contents.


77. Binary Files

C++ can work with binary files:

std::ofstream file(
    "data.bin",
    std::ios::binary
);

Binary serialization requires careful design because directly writing arbitrary C++ objects to disk can be unsafe or non-portable.


78. Dynamic Memory

Traditional C++ provides:

int* number = new int(50);

Then:

delete number;

For arrays:

int* numbers = new int[10];

delete[] numbers;

However:

Modern C++ says:

Avoid manual new and delete whenever possible.

Prefer:

std::vector
std::string
std::unique_ptr
std::shared_ptr

79. Smart Pointers

Include:

#include <memory>

unique_ptr

std::unique_ptr<int> number =
    std::make_unique<int>(50);

The object is automatically destroyed when the pointer leaves scope.


80. shared_ptr

std::shared_ptr<int> number =
    std::make_shared<int>(50);

Another pointer can share ownership:

auto another = number;

Use shared_ptr only when shared ownership is genuinely needed.


81. RAII

RAII means resources are tied to object lifetime.

For example:

{
    std::ofstream file("data.txt");

    file << "Hello";
}

When the block ends, the file object is destroyed and its resources are released.

RAII is one of the most important ideas in professional C++.


82. Move Semantics

C++ can transfer resources rather than unnecessarily copying them.

std::string first = "Large text";

std::string second =
    std::move(first);

After the move, first is still valid, but you should not assume that it retains its previous contents.

Move semantics are important when handling large objects and resources efficiently.


83. std::move

Include:

#include <utility>

Then:

std::move(object)

does not itself move anything.

It essentially tells C++:

This object may be treated as something whose resources can be transferred.

The receiving operation determines what happens.


84. std::optional

Sometimes a function might not have a result.

#include <optional>

std::optional<int> findAge(
    const std::string& name
)
{
    if (name == "Mihigo")
        return 20;

    return std::nullopt;
}

Use:

auto result = findAge("Mihigo");

if (result)
{
    std::cout << *result;
}

85. std::variant

A variant can contain one of several specified types.

std::variant<int, double, std::string> value;

value = 100;

value = "Hello";

This is safer than using untyped memory for alternatives.


86. std::tuple

std::tuple<std::string, int, double> person =
{
    "Mihigo",
    20,
    1.75
};

Access:

std::get<0>(person);

Structured binding:

auto [name, age, height] = person;

87. Date and Time

C++ provides <chrono>.

Example for measuring execution time:

#include <chrono>

auto start =
    std::chrono::steady_clock::now();

// Code

auto end =
    std::chrono::steady_clock::now();

auto duration =
    std::chrono::duration_cast<
        std::chrono::milliseconds
    >(end - start);

std::cout << duration.count()
          << " ms";

88. Random Numbers

Use the modern random library:

#include <random>

Example:

std::random_device device;

std::mt19937 generator(device());

std::uniform_int_distribution<int>
    distribution(1, 100);

int number = distribution(generator);

This produces a number from 1 to 100.


89. Debugging in Dev-C++

When your program doesn't work, don't immediately rewrite everything.

Determine whether the problem is:

Compilation error
Runtime error
Logic error

Compilation error

The compiler cannot translate your program.

Example:

int age = ;

Runtime error

The program compiles but fails during execution.

Examples:

  • Invalid memory access
  • Division by zero
  • Unexpected input

Logic error

The program runs but produces the wrong result.

Example:

int average = total / 2;

when there are actually five values.


90. Debugging Strategy

When something fails:

  1. Read the error message.
  2. Identify the file.
  3. Identify the line.
  4. Read the surrounding code.
  5. Determine what the program expected.
  6. Determine what actually happened.
  7. Fix the underlying cause.
  8. Compile again.
  9. Test again.

Don't simply change code until the error disappears.


91. Header Files

Large programs should be divided into files.

Example:

main.cpp
calculator.cpp
calculator.h

Header:

#ifndef CALCULATOR_H
#define CALCULATOR_H

int add(int a, int b);
int subtract(int a, int b);

#endif

Implementation:

#include "calculator.h"

int add(int a, int b)
{
    return a + b;
}

int subtract(int a, int b)
{
    return a - b;
}

Main:

#include <iostream>
#include "calculator.h"

int main()
{
    std::cout << add(10, 5);

    return 0;
}

Add all files to your Dev-C++ project.


92. Header Guards

This:

#ifndef CALCULATOR_H
#define CALCULATOR_H

// declarations

#endif

prevents a header from being processed repeatedly.

You may also encounter:

#pragma once

which is widely supported by modern compilers.


93. Organizing Classes

A professional class is often split into:

Person.h
Person.cpp

Person.h:

#ifndef PERSON_H
#define PERSON_H

#include <string>

class Person
{
private:
    std::string name;

public:
    Person(const std::string& name);

    void introduce() const;
};

#endif

Person.cpp:

#include "Person.h"
#include <iostream>

Person::Person(const std::string& name)
    : name(name)
{
}

void Person::introduce() const
{
    std::cout << "Hello, "
              << name;
}

94. Project Organization

A larger project might look like:

MyApplication/
│
├── MyApplication.dev
│
├── main.cpp
│
├── include/
│   ├── Person.h
│   └── Product.h
│
├── src/
│   ├── Person.cpp
│   └── Product.cpp
│
├── data/
│
└── README.txt

Dev-C++ projects can be organized this way even though the exact project-management features depend on the Dev-C++ version you are using.


95. C++ Compilation

Your source code:

.cpp

is processed by a compiler.

Conceptually:

C++ source
     ↓
Preprocessor
     ↓
Compiler
     ↓
Object code
     ↓
Linker
     ↓
Executable

Understanding this helps explain errors such as:

undefined reference
multiple definition
file not found

96. Compiler Errors vs Linker Errors

A compiler error might be:

expected ';'

A linker error might be:

undefined reference to ...

For example, declaring:

int add(int a, int b);

but never providing the implementation can cause a linker error.


97. C++ Standards

C++ has evolved over time.

Important standards include:

C++98
C++03
C++11
C++14
C++17
C++20
C++23

Modern C++ development generally means learning concepts introduced in C++11 and later.

However, the exact C++ standard available in Dev-C++ depends on the compiler bundled with the particular Dev-C++ distribution.

Check your compiler before relying on newer language features.


98. Dev-C++ and Modern C++

Dev-C++ is useful for learning C++, especially because it keeps the environment relatively simple.

However, Dev-C++ itself is an IDE, not the C++ language.

The compiler does the actual compilation.

Therefore:

Dev-C++ ≠ C++ compiler

Your Dev-C++ installation may use a GCC/MinGW compiler.

If a newer C++ feature doesn't work, check:

  1. Which compiler Dev-C++ is using.
  2. Which GCC version is installed.
  3. Which language standard is enabled.
  4. Whether your Dev-C++ version supports the relevant compiler configuration.

Do not conclude that a C++ feature doesn't exist merely because an old compiler rejects it.


99. CMake

As you become professional, learn a build system such as CMake.

A basic CMakeLists.txt might contain:

cmake_minimum_required(VERSION 3.20)

project(MyApplication)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(
    MyApplication
    main.cpp
)

Dev-C++ is excellent for learning the language, but professional C++ development usually requires familiarity with build systems, compilers, IDEs, debuggers and command-line tools beyond one IDE.


100. Testing

A professional programmer doesn't simply ask:

Does it compile?

Ask:

Does it behave correctly?

For example:

int add(int a, int b)
{
    return a + b;
}

Test:

if (add(2, 3) != 5)
{
    std::cout << "Test failed";
}

For larger projects, learn a dedicated testing framework such as GoogleTest or Catch2.


101. Assertions

Include:

#include <cassert>

Then:

assert(add(2, 3) == 5);

Assertions are useful for detecting conditions that should always be true during development.


102. Git

Learn Git alongside C++.

Basic commands:

git init
git add .
git commit -m "Initial version"

Useful concepts:

repository
commit
branch
merge
remote
pull
push

Professional programming isn't only about writing code. You must also manage code.


103. Multithreading

C++ supports threads.

#include <thread>

void work()
{
    std::cout << "Working...";
}

int main()
{
    std::thread worker(work);

    worker.join();

    return 0;
}

A thread executes independently of the calling thread.


104. Mutexes

Multiple threads accessing shared data can create race conditions.

Use synchronization mechanisms such as:

std::mutex

Example:

#include <mutex>

std::mutex mutex;

void update()
{
    std::lock_guard<std::mutex> lock(mutex);

    // protected operation
}

Concurrency should be learned after you are comfortable with normal sequential C++.


105. Atomic Variables

For certain shared values:

#include <atomic>

std::atomic<int> counter(0);

Atomic operations can avoid some forms of data race when used correctly.

Concurrency is a deep subject. Don't assume that adding atomic or mutex automatically makes a multithreaded program correct.


106. Performance

C++ is famous for performance, but:

Fast code is not automatically good code.

First make the program:

Correct
Readable
Maintainable

Then measure.

Use profiling and benchmarking to discover actual bottlenecks.

Common performance factors include:

Algorithm choice
Memory allocation
Cache behavior
I/O
Data structures
Copies
Synchronization
CPU usage

107. Algorithm Complexity

You should understand Big-O notation.

Examples:

O(1)
O(log n)
O(n)
O(n log n)
O(n²)

For example, searching every element in a vector is generally:

O(n)

Binary search on sorted data can be:

O(log n)

Choosing a better algorithm often matters much more than micro-optimizing individual lines.


108. Memory Safety

Always think about:

  • Who owns this object?
  • How long does it live?
  • Can this pointer be null?
  • Can this reference become invalid?
  • Can this iterator become invalid?
  • Can this container reallocate?
  • Can this memory be accessed after destruction?

Many serious C++ bugs are lifetime or ownership bugs.


109. Avoid Dangerous Patterns

Avoid unnecessary:

new
delete
malloc
free

Avoid returning pointers or references to local variables:

int* bad()
{
    int number = 10;

    return &number;
}

number stops existing when the function ends.

Prefer value return:

int good()
{
    return 10;
}

110. Professional C++ Principles

Prefer RAII

Let objects manage resources.

Prefer standard containers

Use:

std::vector
std::string
std::map

instead of unnecessarily implementing your own equivalents.

Prefer const

If something shouldn't change, express that.

Prefer clear interfaces

Functions should have clear responsibilities.

Avoid giant classes

Break complex systems into smaller components.

Avoid unnecessary inheritance

Composition is often simpler.

Don't optimize blindly

Measure first.


111. Project 1 — Calculator

Build a calculator supporting:

Addition
Subtraction
Multiplication
Division
Remainder

Example:

===== CALCULATOR =====

First number: 20
Operator: *
Second number: 5

Result: 100

Required concepts:

Input
Output
Functions
switch
Conditions
Error handling

112. Project 2 — Number Guessing Game

Generate a random number between 1 and 100.

The player repeatedly guesses.

Display:

Too high
Too low
Correct

Track the number of attempts.

Upgrade it with:

Difficulty levels
High-score tracking
Replay
Hints

113. Project 3 — Student Management System

Create:

Student ID
Name
Age
Course
Marks

Functions:

Add
View
Search
Update
Delete
Calculate average

Use:

struct Student

and:

std::vector<Student>

Then add file storage.


114. Project 4 — Contact Manager

Store:

Name
Phone
Email
Address

Features:

Add contact
Edit contact
Delete contact
Search contact
List contacts
Save contacts
Load contacts

This is a good introduction to CRUD programming.


115. Project 5 — Expense Tracker

Store:

Description
Amount
Category
Date

Features:

Add expense
List expenses
Search
Delete
Calculate total
Calculate category totals
Save
Load

Upgrade it with monthly reports.


116. Project 6 — Inventory Management System

Store:

Product ID
Product name
Category
Price
Quantity

Implement:

Add product
Edit product
Delete product
Search
Increase stock
Decrease stock
Calculate stock value
Generate report

Use classes when the program becomes sufficiently complex.


117. Project 7 — Library Management System

Classes:

Book
Member
Library

Features:

Add book
Remove book
Search book
Register member
Borrow book
Return book
List available books

This project is excellent for learning OOP.


118. Project 8 — Banking System

Create:

Account
Customer
Transaction
Bank

Features:

Create account
Deposit
Withdraw
Transfer
Balance
Transaction history

Use:

Encapsulation
Classes
Vectors
Maps
Exceptions
File storage

This should be treated as an educational simulation, not a real banking system.


119. Project 9 — Text-Based Game

Create a game such as:

Adventure game
Dungeon game
Quiz game
RPG
Strategy game

Implement:

Player
Enemies
Inventory
Health
Experience
Levels
Combat
Save/load

This teaches object-oriented design and state management.


120. Project 10 — Complete Business Management System

Your final project should combine everything you've learned.

Possible modules:

Authentication
Users
Customers
Products
Inventory
Sales
Expenses
Reports
Settings
File/database storage
Logging

Structure:

Application
│
├── Authentication
├── Users
├── Customers
├── Products
├── Inventory
├── Sales
├── Reports
├── Storage
└── Utilities

This is the point where you're no longer simply learning syntax.

You're engineering software.


121. Rapid Learner Method

Because you are approaching C++ as a rapid learner, don't spend days memorizing syntax.

For every concept:

Understand
↓
Type the example yourself
↓
Change it
↓
Break it
↓
Fix it
↓
Build something with it

For example, after learning vectors, don't merely read:

std::vector<int>

Build:

Student list
Product list
Shopping cart
Contact list

122. The 80/20 C++ Knowledge

If you want to become productive quickly, master these first:

Variables
Data types
Input/output
Conditions
Loops
Functions
Strings
Vectors
Structs
Classes
References
Pointers
STL
Algorithms
Files
Exceptions
RAII
Smart pointers
Templates
Debugging
Git
CMake

These concepts provide an enormous practical foundation.


123. Recommended Learning Order

Stage 1 — Foundations

Learn:

Program structure
Variables
Types
Input/output
Operators
Conditions
Loops

Build:

Calculator
Number guessing game
Grade calculator

Stage 2 — Problem Solving

Learn:

Functions
Arrays
Strings
Structures
Algorithms

Build:

Contact manager
Student system
Expense tracker

Stage 3 — OOP

Learn:

Classes
Objects
Constructors
Destructors
Encapsulation
Inheritance
Polymorphism
Composition

Build:

Library system
Banking simulation
Inventory system

Stage 4 — Modern C++

Learn:

vector
map
set
lambda
auto
templates
optional
variant
smart pointers
RAII
move semantics

Build:

Professional CLI application

Stage 5 — Software Engineering

Learn:

Multiple files
Git
Testing
CMake
Debugging
Logging
Architecture

Build:

Large multi-module application

Stage 6 — Advanced C++

Learn:

Concurrency
Atomics
Performance
Memory models
Networking
System programming
Advanced templates
Design patterns

Then specialize.


124. Skills of a Professional C++ Programmer

A professional C++ programmer should eventually be able to:

  • Read unfamiliar C++ code.
  • Design classes.
  • Choose appropriate data structures.
  • Write reusable functions.
  • Manage object lifetime.
  • Understand pointers and references.
  • Use RAII.
  • Use STL effectively.
  • Debug crashes.
  • Understand compiler errors.
  • Understand linker errors.
  • Work with multiple files.
  • Build large projects.
  • Write tests.
  • Use Git.
  • Use CMake.
  • Profile programs.
  • Understand concurrency.
  • Write maintainable code.
  • Review other people's code.
  • Understand the cost of abstractions.
  • Read documentation.
  • Learn unfamiliar libraries independently.

125. C++ Cheat Sheet

Output

std::cout << "Hello";

Input

std::cin >> value;

String input

std::getline(std::cin, text);

Condition

if (condition)
{
}

Loop

for (int i = 0; i < 10; i++)
{
}

Function

int add(int a, int b)
{
    return a + b;
}

Vector

std::vector<int> values;

Add

values.push_back(10);

Class

class Person
{
private:
    std::string name;

public:
    Person(const std::string& name)
        : name(name)
    {
    }
};

Pointer

int* pointer = &value;

Reference

int& reference = value;

Smart pointer

auto pointer =
    std::make_unique<int>(10);

File

std::ofstream file("data.txt");

Exception

throw std::runtime_error("Error");

Lambda

auto add = [](int a, int b)
{
    return a + b;
};

126. Final Learning Challenge

After completing this guide, build one application without following a tutorial.

Do not copy a project from YouTube.

Design it yourself.

Your application should contain:

At least 5 classes
At least 3 data structures
File persistence
Input validation
Error handling
Multiple source files
Functions
OOP
STL
RAII
Tests
Git repository
Documentation

For example:

Business Management System

Architecture:

                Application
                     │
       ┌─────────────┼─────────────┐
       │             │             │
   Customers      Products      Users
       │             │             │
       └─────────────┼─────────────┘
                     │
                 Transactions
                     │
                 Reporting
                     │
                  Storage

127. The Professional Transition

Your development should progress through these levels:

Level 1

I can write C++ syntax.

Level 2

I can solve programming problems.

Level 3

I can build C++ applications.

Level 4

I understand memory and object lifetime.

Level 5

I can structure large C++ projects.

Level 6

I can debug, test and optimize C++ software.

Level 7

I can design professional C++ systems.

That final level is the objective of this guide.


128. Final Advice

Don't measure your C++ progress by how many keywords you can memorize.

Measure it by what you can build.

Start with:

Hello World

Then:

Calculator

Then:

Number Guessing Game

Then:

Student Management System

Then:

Expense Tracker

Then:

Inventory System

Then:

Library System

Then:

Business Management System

Finally:

A completely original application

At that point, C++ stops being a subject you are studying and becomes a tool you use to solve real problems.

Learn the syntax.

Understand the memory model.

Master the Standard Library.

Build constantly.

Debug your own mistakes.

Read other people's code.

Design larger systems.

Then specialize.

That is the path from a C++ beginner using Dev-C++ to a professional C++ programmer.