Standard Library Overview
C++ is built from three main components: the core language, the C++ Standard Library, and the Standard Template Library (STL).
Trigraphs
Trigraph sequences like ??= represent characters not available on some keyboards (e.g., #). While most compilers disable trigraph replacement by default, g++ enables it. To safely write two consecutive question marks, use string literal concatenation ("...?""?...") or escape one ("...?\?...").
Data Types and Sizes
A byte consists of 8 bits. Common type sizes (minimum per standard):
char: 1 byteint: 4 byteslong: 4 bytes (often 8 on 64-bit systems)long long: 8 bytesfloat: 4 bytes (≈7 decimal digits precision)double: 8 bytes (≈16 decimal digits precision)
Floating-point representation explains precision artifacts:
float a = 77777.7777777f; // Stored as 77777.781250 due to binary rounding
double b = 77777.777777777; // Stored more accurately as 77777.777778
Type Aliasing with typedef
typedef existing_type new_alias;
C++ Type Conversions
static_cast
For related types without runtime checks:
int value = 42;
double result = static_cast<double>(value);
dynamic_cast
Safe downcasting with runtime type checking:
class Base { virtual ~Base() = default; };
class Derived : public Base {};
Base* base_ptr = new Derived();
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
const_cast
Modifies constness (use cautiously):
const int constant = 100;
int& mutable_ref = const_cast<int&>(constant);
reinterpret_cast
Low-level reinterpreting of bit patterns:
int integer = 0x41414141;
float reinterpretation = reinterpret_cast<float&>(integer);
int* int_ptr = new int(64);
char* byte_ptr = reinterpret_cast<char*>(int_ptr);
Constants and Modifiers
Prefer uppercase for constants:
const int MAX_SIZE = 256;
Booleans represent logical states, not numeric values.
Signed vs Unsigned Behavior
unsigned short us = 50000;
short s = us; // Results in -15536 due to two's complement interpretation
Type Qualifiers and Storage Classes
| Qualfiier/Class | Description |
|---|---|
| const | Immutable value |
| volatile | Value may change externally (e.g., hardware registers) |
| mutable | Allows modification in const member functions |
| static | Internal linkage (file scope) or persistent local storage |
| extern | Declares external linkage (defined elsewhere) |
| thread_local | Per-thread instance with automatic lifetime |
Operators
Key miscellaneous operators:
| Operator | Purpose |
|---|---|
| sizeof | Byte size of type/expression |
| ? : | Conditional evaluation |
| , | Sequential evaluation (returns last expression) |
| . | Direct member access |
| -> | Pointer-to-member access |
| &, * | Address-of and dereference |
Lambda Expressions
Syntax: [capture](params) -> return_type { body }
Capture Modes
- Value capture:
[x]– copies variable (immutable unlessmutable) - Reference capture:
[&x]– references variable (lifetime caution required) - Implicit capture:
[=](all by value) or[&](all by reference) - Init capture:
[z = x + 5]– creates new initialized variable
class Widget {
int data = 42;
public:
void process() {
auto lambda = [*this] { return data * 2; }; // Captures entire object by value
}
};
Random Number Generation
Always seed with srand() before using rand() to avoid identical sequences across runs.
Arrays
Passing to Functions
All these declarations are equivalent (decay to pointer):
void func(int* arr);
void func(int arr[]);
void func(int arr[10]);
Returning Arrays
Return pointers to static or dynamically allocated arrays:
int* get_static_array() {
static int arr[] = {1, 2, 3};
return arr;
}
int* get_dynamic_array() {
int* arr = new int[3]{4, 5, 6};
return arr; // Caller must delete[]
}
Pointer Arithmetic
Incrementing a pointer advances by sizeof(type) bytes:
int arr[] = {10, 20, 30};
int* ptr = arr;
++ptr; // Now points to arr[1] (address + 4 bytes on typical systems)
Subtracting pointers yields element count between them.
Date and Time
Use <ctime> with time_t and tm structures:
time_t current_time = time(nullptr);
char* time_str = ctime(¤t_time);
I/O Streams
cout: Buffered standard outputcin: Standard inputcerr: Unbuffered error output (immediate)clog: Buffered logging output
Structures
struct Point {
double x, y;
};
typedef struct {
char name[50];
int id;
} Student;
Classes and Objects
Member Initialization
Prefer initialization lists over assignment in constructors:
class Rectangle {
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
};
Copy Constructor
Required for deep copying when managing resources:
class Buffer {
char* data;
size_t size;
public:
Buffer(const Buffer& other) : size(other.size) {
data = new char[size];
std::copy(other.data, other.data + size, data);
}
};
Invoked during: object initialization, pass-by-value, and return-by-value.
Friend Functions
Grants non-member functions access to private members:
class Secret {
int code;
friend void reveal(const Secret& s); // Full access granted
};
this Pointer
Implicit pointer to current object instance:
bool Container::is_larger_than(const Container& other) {
return this->volume() > other.volume();
}
Static Members
Shared across all class instances:
class Counter {
public:
static int count;
Counter() { ++count; }
};
int Counter::count = 0; // Definition outside class
Static member functions can only access static members.
Inheritance
Public inheritance models "is-a" relationships:
class Vehicle { /* ... */ };
class Car : public Vehicle { /* ... */ };
Access rules:
- Public inheritance: Base public → derived public, base protected → derived protected
- Protected inheritance: Base public/protected → derived protected
- Private inheritance: Base public/protected → derived private
Operator Overloading
Member function version (unary/binary):
Vector Vector::operator+(const Vector& rhs) const {
return Vector(x + rhs.x, y + rhs.y);
}
Non-member version (requires friend declaration):
friend Vector operator+(const Vector& lhs, const Vector& rhs);
Polymorphism
Virtual functions enable runtime dispatch:
class Shape {
public:
virtual double area() const = 0; // Pure virtual (abstract)
virtual ~Shape() = default;
};
class Circle : public Shape {
double radius;
public:
double area() const override {
return 3.14159 * radius * radius;
}
};
File I/O
Use <fstream>:
ifstream: Input from filesofstream: Output to filesfstream: Bidirectional file access
Exception Handling
Structured error handling with try/catch:
try {
risky_operation();
} catch (const std::invalid_argument& e) {
handle_error(e.what());
} catch (...) {
handle_unknown_error();
}
Custom exceptions inherit from std::exception:
class MyError : public std::exception {
public:
const char* what() const noexcept override {
return "Custom error occurred";
}
};
Preprocessor Directives
Conditional compilation:
#ifdef DEBUG
std::cerr << "Debug info\n";
#endif
#if 0
// Disabled code block
#endif