Cpp

C++


How to C++

Manual Memory Management

C++ doesn’t have garbage collection. Use smart pointers to manage memory automatically.

std::unique_ptr<int> ptr = std::make_unique<int>(10);  // Automatically managed memory
// No need to call delete, memory is freed when ptr goes out of scope

Header Files and Separate Compilation

Use header files for declarations and source files for definitions. Use include guards to prevent multiple inclusions.

#ifndef MY_HEADER_H
#define MY_HEADER_H
// Declarations go here
#endif

Strong Typing and Explicit Casting

C++ is strongly typed. Use explicit casting for type conversions.

double x = 5.5;
int y = static_cast<int>(x);  // Explicit cast to int

Object-Oriented Features

Use `virtual` for methods you want to override in derived classes. Use `override` to make intentions clear.

class Base {
public:
    virtual void foo() { /*...*/ }
};

class Derived : public Base {
public:
    void foo() override { /*...*/ }
};

Standard Template Library (STL)

Use STL containers and algorithms for common tasks.

std::vector<int> vec = {1, 2, 3};
std::sort(vec.begin(), vec.end());  // Sorts the vector

Move Semantics and Rvalue References

Use `std::move` to transfer ownership of resources.

std::string str1 = "Hello";
std::string str2 = std::move(str1);  // str1 is now in a valid but unspecified state

Templates and Generic Programming

Use templates for generic functions and classes.

template <typename T>
T add(T a, T b) {
    return a + b;
}

int result = add(3, 4);  // result is 7

Core Language Basics

Syntax Rules

// πŸ“œ Basic syntax
int main() {
    int x = 10;          // Variable declaration
    std::cout << x;      // Output: 10
    return 0;            // Return statement
}

Primitive Data Types

// 🏷️ Primitive types
int integer = 42;                // Integer
double floating = 3.14;          // Double-precision floating point
char character = 'A';            // Single character
bool boolean = true;             // Boolean (true/false)

Variables and Constants

// πŸ“¦ Variable declarations
int x = 10;                      // Mutable variable
const int y = 20;                // Immutable constant
constexpr int z = 30;            // Compile-time constant

Operators

// βž• Arithmetic operators
int sum = x + y;                 // Addition
int diff = x - y;                // Subtraction

// πŸ”€ Logical operators
bool result = (x > 5) && (y < 30); // Logical AND

// πŸ”„ Ternary operator
int max = (x > y) ? x : y;       // Conditional assignment

Memory Management

Stack vs Heap

// πŸ—οΈ Stack allocation
int stackVar = 10;               // Allocated on the stack

// πŸ—οΈ Heap allocation
int* heapVar = new int(20);      // Allocated on the heap
delete heapVar;                  // Manual deallocation required

Smart Pointers

// 🧠 Smart pointers
std::unique_ptr<int> uPtr = std::make_unique<int>(10); // Unique ownership
std::shared_ptr<int> sPtr = std::make_shared<int>(20); // Shared ownership
std::weak_ptr<int> wPtr = sPtr;                        // Weak reference

RAII Principle

// πŸ›‘οΈ RAII (Resource Acquisition Is Initialization)
class Resource {
public:
    Resource() { /* Acquire resource */ }
    ~Resource() { /* Release resource */ }
};

Common Pitfalls

// ⚠️ Memory leaks
int* leak = new int(10);        // Never deleted

// ⚠️ Dangling pointers
int* ptr = new int(10);
delete ptr;
*ptr = 20;                      // Undefined behavior

Object-Oriented Programming

Classes vs Structs

// πŸ›οΈ Class (default access: private)
class MyClass {
    int privateVar;             // Private by default
public:
    int publicVar;              // Explicitly public
};

// πŸ›οΈ Struct (default access: public)
struct MyStruct {
    int publicVar;              // Public by default
private:
    int privateVar;             // Explicitly private
};

Use classes for encapsulation and structs for data grouping.

Constructors

// πŸ—οΈ Default/Parameterized/Copy/Move Constructors
class Example {
public:
    Example() {}                              // Default
    Example(int x) : val(x) {}                // Parameterized
    Example(const Example& other) {           // Copy
        val = other.val;
    }
    Example(Example&& other) noexcept {       // Move
        val = std::exchange(other.val, 0);
    }
private:
    int val;
};

Constructors initialize objects. Use initializer lists for efficiency.

Destructors

// 🧹 Destructor (RAII cleanup)
class FileHandler {
public:
    ~FileHandler() {
        if (file) fclose(file);   // Release resource
    }
private:
    FILE* file;
};

Destructors automatically release resources when objects go out of scope.

Inheritance Types

// 🧬 Single inheritance
class Derived : public Base { /*...*/ };

// 🧬 Multiple inheritance
class Derived : public Base1, public Base2 { /*...*/ };

// 🧬 Virtual inheritance (prevents diamond problem)
class Derived : virtual public Base { /*...*/ };

Use public inheritance for "is-a" relationships. Avoid multiple inheritance unless necessary.

Polymorphism

// 🎯 Virtual functions and overriding
class Shape {
public:
    virtual double area() const = 0;  // Pure virtual (abstract class)
};

class Circle : public Shape {
public:
    double area() const override {    // Must implement
        return 3.14 * radius * radius;
    }
};

Mark base class methods as virtual. Use override to ensure correct polymorphism.

Encapsulation

// πŸ”’ Private members with public getters/setters
class BankAccount {
public:
    double getBalance() const { return balance; }
    void deposit(double amount) { balance += amount; }
private:
    double balance = 0;   // Hidden internal state
};

Expose minimal interfaces. Keep data private to enforce invariants.

Rule of Five

// πŸ›‘ Manage resources explicitly
class ResourceHolder {
public:
    ResourceHolder() { ptr = new int[100]; }  // Constructor
    ~ResourceHolder() { delete[] ptr; }       // Destructor
    ResourceHolder(const ResourceHolder& other) {  // Copy constructor
        ptr = new int[100];
        std::copy(other.ptr, other.ptr + 100, ptr);
    }
    ResourceHolder& operator=(const ResourceHolder& other) { // Copy assignment
        if (this != &other) {
            delete[] ptr;
            ptr = new int[100];
            std::copy(other.ptr, other.ptr + 100, ptr);
        }
        return *this;
    }
    ResourceHolder(ResourceHolder&& other) noexcept { // Move constructor
        ptr = other.ptr;
        other.ptr = nullptr;
    }
    ResourceHolder& operator=(ResourceHolder&& other) noexcept { // Move assignment
        delete[] ptr;
        ptr = other.ptr;
        other.ptr = nullptr;
        return *this;
    }
private:
    int* ptr;
};

If you define a destructor, copy/move operations, you likely need all five.

Friend Functions/Classes

// 🀝 Granting access to private members
class SecretKeeper {
    friend class TrustedFriend;   // Friend class
    friend void peekSecret(const SecretKeeper&); // Friend function
private:
    int secret = 42;
};

class TrustedFriend {
public:
    static int getSecret(const SecretKeeper& sk) { return sk.secret; }
};

Use friend sparingly to break encapsulation only when necessary.

Static Members

// πŸ”„ Shared class-level data
class Counter {
public:
    static int count;            // Declaration
    Counter() { count++; }
    ~Counter() { count--; }
};
int Counter::count = 0;          // Definition (required)

Static members belong to the class, not individual objects.

Operator Overloading

// βž• Custom operator behavior
class Vector {
public:
    Vector operator+(const Vector& other) const {
        return Vector(x + other.x, y + other.y);
    }
private:
    double x, y;
};

Overload operators to enable natural syntax for custom types.


Standard Template Library (STL)

Containers

// πŸ“¦ STL containers
std::vector<int> vec = {1, 2, 3};       // Dynamic array
std::map<std::string, int> map = {{"a", 1}, {"b", 2}}; // Key-value pairs

Algorithms

// πŸ”§ STL algorithms
std::sort(vec.begin(), vec.end());      // Sort a vector
auto it = std::find(vec.begin(), vec.end(), 2); // Find an element

Iterators

// πŸ”„ Iterators
for (auto it = vec.begin(); it != vec.end(); ++it) {
    std::cout << *it;                   // Access element
}

Modern C++ Features

Auto Type Deduction

// πŸ€– Auto keyword
auto x = 10;                            // x is int
auto y = 3.14;                          // y is double

Move Semantics

// 🚚 Move semantics
std::string str1 = "Hello";
std::string str2 = std::move(str1);     // str1 is now empty

Lambda Expressions

// πŸ‘ Lambda functions
auto lambda = [](int x) { return x * x; };
int result = lambda(5);                 // result is 25

Templates and Generic Programming

Function Templates

// 🧩 Function template
template <typename T>
T add(T a, T b) {
    return a + b;
}

Class Templates

// πŸ›οΈ Class template
template <typename T>
class Box {
public:
    T value;
};

Error Handling and Safety

Exception Handling

// 🚨 Exception handling
try {
    throw std::runtime_error("Error!");
} catch (const std::exception& e) {
    std::cerr << e.what();
}

Const Correctness

// πŸ”’ Const correctness
const int x = 10;
int y = x;                              // Allowed
x = 20;                                 // Error: x is const

Why Solo Dev?

This reference website is not for beginners
Solo Dev is strictly for devs who already know the game and need a beautiful cheat sheet on their second monitor which looks better than GeeksforGeeks


this portion goes away when you shrink the screen ;)

Our popular languages: