C++ Programming Tutorial
Learn modern C++ step-by-step — from basics to advanced features like templates, STL, and smart pointers. Clear explanations with practical, runnable examples.
C++ Functions
Functions encapsulate reusable logic. C++ functions have a return type, name, and parameter list. The language supports overloading, default arguments, pass by value/reference, and lambda expressions.
Defining and Calling Functions
basics.cpp
#include <iostream>
#include <string>
// Function declaration (prototype)
int add(int a, int b);
std::string greet(const std::string& name);
int main() {
std::cout << add(3, 5) << "
"; // 8
std::cout << greet("Alice") << "
"; // Hello, Alice!
return 0;
}
// Function definitions
int add(int a, int b) {
return a + b;
}
std::string greet(const std::string& name) {
return "Hello, " + name + "!";
}Pass by Value, Reference, and const Reference
passing.cpp
#include <iostream>
#include <vector>
// Pass by value — copies the argument (safe but may be slow for large objects)
void by_value(int x) {
x = 99; // does NOT affect the original
}
// Pass by reference — modifies the original
void by_reference(int& x) {
x = 99; // DOES affect the original
}
// Pass by const reference — read-only, no copy (best for large objects)
void print_vector(const std::vector<int>& v) {
for (int n : v) std::cout << n << " ";
std::cout << "
";
}
int main() {
int a = 10;
by_value(a);
std::cout << a << "
"; // 10 (unchanged)
by_reference(a);
std::cout << a << "
"; // 99 (changed)
std::vector<int> nums{1, 2, 3, 4, 5};
print_vector(nums); // no copy, cannot modify
return 0;
}Function Overloading
overloading.cpp
#include <iostream>
#include <string>
// Same name, different parameter types — compiler picks the right one
int max_val(int a, int b) { return (a > b) ? a : b; }
double max_val(double a, double b) { return (a > b) ? a : b; }
std::string max_val(const std::string& a, const std::string& b) {
return (a.size() > b.size()) ? a : b;
}
int main() {
std::cout << max_val(3, 7) << "
"; // 7 (int version)
std::cout << max_val(3.14, 2.71) << "
"; // 3.14 (double version)
std::cout << max_val("hi", "hello") << "
"; // hello (string version)
return 0;
}Default Arguments
defaults.cpp
#include <iostream>
void log(const std::string& msg, const std::string& level = "INFO") {
std::cout << "[" << level << "] " << msg << "
";
}
double power(double base, int exp = 2) {
double result = 1;
for (int i = 0; i < exp; ++i) result *= base;
return result;
}
int main() {
log("Server started"); // [INFO] Server started
log("Connection failed", "ERROR"); // [ERROR] Connection failed
std::cout << power(5) << "
"; // 25 (default exp=2)
std::cout << power(2, 10) << "
"; // 1024
return 0;
}Lambda Expressions (C++11)
lambdas.cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Basic lambda
auto add = [](int a, int b) { return a + b; };
std::cout << add(3, 5) << "
"; // 8
// Lambda with capture
int multiplier = 3;
auto times = [multiplier](int x) { return x * multiplier; };
std::cout << times(7) << "
"; // 21
// Lambda with algorithms
std::vector<int> nums{5, 2, 8, 1, 9, 3};
std::sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b; // descending order
});
for (int n : nums) std::cout << n << " "; // 9 8 5 3 2 1
std::cout << "
";
// Generic lambda (C++14)
auto print = [](const auto& x) { std::cout << x << "
"; };
print(42);
print("hello");
print(3.14);
return 0;
}Best Practices
- Pass small types (int, double) by value and large types (string, vector, custom classes) by
const&. - Use
[[nodiscard]]on functions whose return value should not be ignored (C++17). - Declare functions before use — put prototypes in header files for multi-file projects.
- Keep functions short and focused — each function should do one thing well.
- Use lambdas for short, one-off operations passed to algorithms or callbacks.
- Avoid output parameters — prefer returning values (use structured bindings for multiple returns).
Keep Practicing
Use the online compiler to run every example and experiment with modifications. The best way to learn C++ is by writing code — even small programs build strong foundations.