C with classes, templates, STL, and modern features. Game engines, browsers, and operating systems use it.
#include <iostream>
#include <string>
using namespace std;
int main() {
cout << "Hello, World!" << endl;
string name = "Mayank";
cout << "Name: " << name << endl;
return 0;
}
// Compile: g++ -std=c++17 hello.cpp -o hello
#include <iostream>
#include <string>
using namespace std;
int main() {
int age = 15;
double pi = 3.14159265;
char grade = 'A';
bool passed = true;
string name = "Mayank";
auto x = 42; // int
auto y = 3.14; // double
auto z = "hello"; // const char*
cout << name << " age=" << age << endl;
cout << "pi=" << pi << endl;
cout << "passed=" << passed << endl;
return 0;
}
#include <iostream>
using namespace std;
void modify(int &ref, int *ptr) {
ref = 100;
*ptr = 200;
}
int main() {
int a = 10;
int &r = a; // reference
int *p = &a; // pointer
cout << "a=" << a << " r=" << r << " *p=" << *p << endl;
modify(a, p);
cout << "a=" << a << " r=" << r << " *p=" << *p << endl;
return 0;
}
Same function name, different parameters. Default arguments. Inline functions.
#include <iostream>
using namespace std;
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
string add(string a, string b) { return a + b; }
int power(int base, int exp = 2) {
int result = 1;
for (int i = 0; i < exp; i++) result *= base;
return result;
}
int main() {
cout << add(3, 4) << endl;
cout << add(3.14, 2.72) << endl;
cout << add(string("Hello "), string("World")) << endl;
cout << power(5) << endl;
cout << power(2, 10) << endl;
return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {10, 20, 30, 40, 50};
// Range-based for
for (const auto &n : nums) cout << n << " ";
cout << endl;
// Structured bindings (C++17)
vector<pair<string,int>> items = {{"a",1},{"b",2},{"c",3}};
for (const auto &[key, val] : items)
cout << key << "=" << val << ", ";
cout << endl;
// if with initializer (C++17)
if (auto it = find(nums.begin(), nums.end(), 30); it != nums.end())
cout << "Found: " << *it << endl;
return 0;
}
Blueprints for objects. Private data, public methods. Constructors build, destructors clean.
#include <iostream>
#include <string>
using namespace std;
class Dog {
private:
string name;
int age;
public:
Dog(string n, int a) : name(n), age(a) {}
~Dog() { cout << name << " destroyed\n"; }
void bark() const { cout << name << ": Woof! (age " << age << ")\n"; }
string getName() const { return name; }
void setAge(int a) { if (a > 0) age = a; }
};
int main() {
Dog d("Rex", 5);
d.bark();
d.setAge(6);
d.bark();
return 0;
}
Child classes inherit from parent. Virtual functions let child classes override behavior.
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Shape {
public:
virtual double area() const = 0;
virtual string type() const = 0;
virtual ~Shape() {}
};
class Circle : public Shape {
double r;
public:
Circle(double r) : r(r) {}
double area() const override { return 3.14159 * r * r; }
string type() const override { return "Circle"; }
};
class Rect : public Shape {
double w, h;
public:
Rect(double w, double h) : w(w), h(h) {}
double area() const override { return w * h; }
string type() const override { return "Rectangle"; }
};
int main() {
vector<unique_ptr<Shape>> shapes;
shapes.push_back(make_unique<Circle>(5));
shapes.push_back(make_unique<Rect>(4, 6));
for (const auto &s : shapes)
cout << s->type() << " area=" << s->area() << endl;
return 0;
}
Write code that works with any type. The compiler generates the specific version for you.
#include <iostream>
#include <string>
using namespace std;
template <typename T>
T max_val(T a, T b) { return (a > b) ? a : b; }
template <typename T>
class Stack {
T items[100];
int top = -1;
public:
void push(T v) { items[++top] = v; }
T pop() { return items[top--]; }
bool empty() const { return top < 0; }
};
int main() {
cout << max_val(3, 7) << endl;
cout << max_val(3.14, 2.72) << endl;
cout << max_val(string("abc"), string("xyz")) << endl;
Stack<int> s;
s.push(10); s.push(20); s.push(30);
while (!s.empty()) cout << s.pop() << " ";
cout << endl;
return 0;
}
Make operators work with your classes. +, ==, <<, [] โ you can define them all.
#include <iostream>
using namespace std;
class Vec2 {
double x, y;
public:
Vec2(double x=0, double y=0) : x(x), y(y) {}
Vec2 operator+(const Vec2 &o) const { return {x+o.x, y+o.y}; }
Vec2 operator*(double s) const { return {x*s, y*s}; }
bool operator==(const Vec2 &o) const { return x==o.x && y==o.y; }
friend ostream& operator<<(ostream &os, const Vec2 &v) {
return os << "(" << v.x << "," << v.y << ")";
}
double& operator[](int i) { return i==0 ? x : y; }
};
int main() {
Vec2 a(1,2), b(3,4);
cout << "a+b=" << a+b << endl;
cout << "a*3=" << a*3 << endl;
cout << "a==b: " << (a==b) << endl;
cout << "a[0]=" << a[0] << endl;
return 0;
}
#include <iostream>
#include <memory>
using namespace std;
class Resource {
string name;
public:
Resource(string n) : name(n) { cout << name << " created\n"; }
~Resource() { cout << name << " destroyed\n"; }
void use() { cout << name << " used\n"; }
};
int main() {
// unique_ptr โ exclusive ownership
auto up = make_unique<Resource>("Unique");
up->use();
// shared_ptr โ shared ownership
auto sp1 = make_shared<Resource>("Shared");
auto sp2 = sp1; // ref count = 2
cout << "ref count: " << sp1.use_count() << endl;
sp1->use();
sp2.reset(); // ref count = 1
// weak_ptr โ observe without owning
weak_ptr<Resource> wp = sp1;
if (auto locked = wp.lock()) locked->use();
return 0;
}
Steal resources instead of copying. && means rvalue reference. std::move enables stealing.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Buffer {
int *data;
size_t size;
public:
Buffer(size_t s) : data(new int[s]), size(s) { cout << "alloc\n"; }
~Buffer() { delete[] data; }
// Move constructor
Buffer(Buffer &&o) noexcept : data(o.data), size(o.size) {
o.data = nullptr; o.size = 0;
}
// Move assignment
Buffer& operator=(Buffer &&o) noexcept {
delete[] data;
data = o.data; size = o.size;
o.data = nullptr; o.size = 0;
return *this;
}
};
int main() {
Buffer a(1024);
Buffer b = move(a); // a is now empty
Buffer c(512);
c = move(b); // b is now empty
return 0;
}
Anonymous functions. Capture variables from surrounding scope. Used everywhere in modern C++.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int offset = 10;
// Basic lambda
auto add = [](int a, int b) { return a + b; };
cout << add(3, 4) << endl;
// Capture by value and reference
auto inc = [offset](int x) { return x + offset; };
cout << inc(5) << endl;
// Mutable lambda
int count = 0;
auto counter = [count]() mutable { return ++count; };
cout << counter() << " " << counter() << endl;
// Lambda with STL
vector<int> v = {5, 3, 1, 4, 2};
sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
for (int n : v) cout << n << " ";
cout << endl;
// Generic lambda (C++14)
auto print = [](auto x) { cout << x << endl; };
print(42); print(3.14); print("hi");
return 0;
}
Compute at compile time. Concepts constrain template parameters to specific types.
#include <iostream>
#include <concepts>
using namespace std;
// Constexpr โ compute at compile time
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n-1);
}
constexpr int fib(int n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
}
// Concepts โ constrain templates
template <typename T>
concept Numeric = integral<T> || floating_point<T>;
template <Numeric T>
T square(T x) { return x * x; }
template <typename T>
concept Addable = requires(T a, T b) { { a + b } -> convertible_to<T>;
};
int main() {
constexpr int f5 = factorial(5); // computed at compile time
cout << "5! = " << f5 << endl;
cout << "fib(10) = " << fib(10) << endl;
cout << square(5) << endl;
cout << square(3.14) << endl;
return 0;
}
vector, map, set, array, unordered_map โ pre-built data structures ready to use.
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <array>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main() {
// Vector โ dynamic array
vector<int> v = {3, 1, 4, 1, 5};
v.push_back(9); v.pop_back();
sort(v.begin(), v.end());
for (int n : v) cout << n << " ";
cout << endl;
// Map โ sorted key-value
map<string, int> ages = {{"Mayank",15},{"Alice",20}};
ages["Bob"] = 12;
for (auto &[k,v] : ages) cout << k << ":" << v << ", ";
cout << endl;
// Set โ unique sorted elements
set<int> s = {5, 3, 1, 3, 5};
cout << "set size: " << s.size() << endl;
// Array โ fixed size
array<int, 5> arr = {10, 20, 30, 40, 50};
cout << "array: ";
for (int n : arr) cout << n << " ";
cout << endl;
// Unordered map โ hash table, fast lookup
unordered_map<string, double> prices = {{"apple",1.5},{"banana",0.75}};
cout << "apple: $" << prices["apple"] << endl;
return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
using namespace std;
int main() {
vector<int> v = {5, 3, 1, 4, 2, 8, 7, 6};
sort(v.begin(), v.end());
cout << "sorted: ";
for (int n : v) cout << n << " ";
cout << endl;
sort(v.begin(), v.end(), greater<int>());
cout << "desc: ";
for (int n : v) cout << n << " ";
cout << endl;
auto it = find(v.begin(), v.end(), 4);
if (it != v.end()) cout << "found at index: " << distance(v.begin(), it) << endl;
int sum = accumulate(v.begin(), v.end(), 0);
cout << "sum: " << sum << endl;
transform(v.begin(), v.end(), v.begin(), [](int x){ return x * 2; });
cout << "doubled: ";
for (int n : v) cout << n << " ";
cout << endl;
int count = count_if(v.begin(), v.end(), [](int x){ return x > 10; });
cout << ">10: " << count << endl;
auto [mn, mx] = minmax_element(v.begin(), v.end());
cout << "min=" << *mn << " max=" << *mx << endl;
return 0;
}
fstream for files, stringstream for string parsing, istream for formatted input.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main() {
// File writing
ofstream out("data.txt");
out << "Hello File!" << endl;
out << 42 << " " << 3.14 << endl;
out.close();
// File reading
ifstream in("data.txt");
string line;
while (getline(in, line)) cout << line << endl;
in.close();
// String stream
stringstream ss("10 20 30");
int a, b, c;
ss >> a >> b >> c;
cout << "parsed: " << a << "," << b << "," << c << endl;
// Build string
stringstream build;
build << "Score: " << 100 << " Name: " << "Mayank";
cout << build.str() << endl;
return 0;
}
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <numeric>
using namespace std;
mutex mtx;
int shared_counter = 0;
void worker(int id) {
for (int i = 0; i < 1000; i++) {
lock_guard<mutex> lock(mtx);
shared_counter++;
}
}
void parallel_sum(const vector<int> &v, int start, int end, int &result) {
result = accumulate(v.begin()+start, v.begin()+end, 0);
}
int main() {
// Thread basics
vector<thread> threads;
for (int i = 0; i < 10; i++)
threads.emplace_back(worker, i);
for (auto &t : threads) t.join();
cout << "counter: " << shared_counter << endl;
// Parallel sum
vector<int> data(1000);
iota(data.begin(), data.end(), 1);
int r1=0, r2=0;
thread t1(parallel_sum, ref(data), 0, 500, ref(r1));
thread t2(parallel_sum, ref(data), 500, 1000, ref(r2));
t1.join(); t2.join();
cout << "sum: " << r1+r2 << endl;
return 0;
}