From Absolute Beginner to Professional Programmer
Table of Contents
- Introduction to C++
- Installing and Using Dev-C++
- Your First C++ Program
- Program Structure
- Comments
- Variables
- Data Types
- Constants
- Output
- Input
- Operators
- Conditional Statements
- Loops
- Functions
- Arrays
- Strings
- Pointers
- References
- Structures
- Enumerations
- Object-Oriented Programming
- Classes and Objects
- Constructors and Destructors
- Encapsulation
- Inheritance
- Polymorphism
- Abstraction
- Operator Overloading
- Static Members
- Namespaces
- Header Files
- Multiple Source Files
- The Standard Library
- Vectors
- Maps
- Sets
- Iterators
- Algorithms
- Lambda Functions
- Templates
- Exception Handling
- File Handling
- Dynamic Memory
- Smart Pointers
- RAII
- Move Semantics
- Modern C++
- Date and Time
- Random Numbers
- Debugging
- C++ Project Organization
- Building Larger Programs
- CMake and Professional Development
- Testing
- Git
- Multithreading
- Performance
- Security
- Professional C++ Practices
- Projects
- Rapid-Learning Roadmap
- 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:
- Read the error message.
- Identify the file.
- Identify the line.
- Read the surrounding code.
- Determine what the program expected.
- Determine what actually happened.
- Fix the underlying cause.
- Compile again.
- 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:
- Which compiler Dev-C++ is using.
- Which GCC version is installed.
- Which language standard is enabled.
- 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.

0 Comments