Show Menu
Cheatography

C++ Cheat Sheet (DRAFT) by

This is a draft cheat sheet. It is a work in progress and is not finished yet.

enum

enum Color {
    COLOR_RED, // assigned 0
    COLOR_BLUE // assigned 1
};
Color color=COLOR_RED;

// input/output
int input{};
std::cin >> input;
Color color=static_cast<Color>(input)
Prefer enum class if possible (C++11)

enum class (C++11)

enum class Color {
    RED,
    BLUE
};
Color color=Color::RED;
std::cout << static_cast<int>(color);

typedef

typedef double distance_t;
using distance_t = double; // C++11

struct

struct Employee {
    short id;
    int age;
};
Employee joe = {1, 42}; // initializer list
joe.age = 43; // member selection operator

std::v­ector

#include <vector>
std::vector<int> tab {1, 2, 3, 4};
tab[0] // or tab.at(0) with bounds checking
tab.size()
tab.resize(3); // expensive

// capacity & stack-like behavior
std::vector<int> stack;
stack.reserve(5); // set capacity
stack.push_back(3);
int x = stack.back(); // top of stack
stack.pop_back();
capacity = allocated memory
length = active values
Setting capacity avoid resizing the array

std::tuple - C++11

#include <tuple>
// using namespace std;
tuple<int, double> t = make_tuple(3, 6.7);
int a = get<0>(t);

// std::tuple<int, double> foo();
int a;
double b;
std::tie(a,b) = foo()
auto [a, b] = foo(); // C++17

std::array - C++11

#include <array>
std::array<int, 3> tab {1, 2, 3};
tab[0] // or tab.at(0) with bounds checking
tab.size() // length not sizeof()
 

References

int value=5;
int &ref=value; // non-const ref
const int value=5;
const int &ref=value; // treats value as const
References are similar to const pointers (cannot change address)

Pointers

int value=5;
int *const p=&value; //const pointer
const int value=5;
const int *p; // non-const pointer to const int

// const pointer to const value
const int *const p=&value; 

// int foo(int x);
int (*ptr)(int); // function pointer
int (*const ptr)(int) = foo; // const pointer
#include <functional>
std::function<int(int)> ptr = foo; // C++11
ptr(5); // implicit dereference or (*ptr)(5)

new & delete (dynamic alloca­tion)

// scalar version
int *p=new int(3);
delete p;

// array version
int *p = new int[3] {1, 2, 3}; // C++11 syntax
delete[] p;

Classes

class Foo {
private:
    // non-static member initialization
    int m_value = 10; // C++11
    // static member variable //
    static int m_id;
public:
    // constructor and destructor
    Foo(int value):m_value(value);
    ~Foo();
   // copy constructor
    Foo(const Foo& foo)
               :m_value(foo.m_value);

    // static member function
    static int get_id(); // see definition
    // const member function
    void print() const;
    // friend function
    friend void reset(Foo &foo);
};

Foo(6); // anonymous object

// static
int Foo::m_id=0;
int Foo::get_id() { return m_id; } // no static
int id = Foo::get_id();

// const member function
void Foo::print() const { whatever }
const Foo foo;
foo.print(); // no constness violation

// friend function
friend void reset(Foo &foo) { foo.m_value=0; }
1) no implicit default constr­uctor if at least one constr­uctor provided
2) implicit copy constr­uctor and overloaded operator= use memberwise initia­liz­ation (shallow copy)

std::i­nit­ial­ize­r_list (C++11)

#include <initalizer_list>
int m_size;
int *m_array;

// prevent shallow copy (dynamic mem alloc)
Foo(const Foo& foo) = delete; 
Foo& operator=(const Foo& foo) = delete;

Foo(const std::initializer_list<int>& list)
    :m_size(static_cast<int>(list.size))
{
    // deep copy with for-each loop
    int count=0; 
    for (auto& value : list)
        m_array[count++] = value;
}
Foo& operator=(const std::initializer_list<int> &list)
{
    // same but delete[] m_array
    // if same size (no need for new or delete)
    // deep copy
}

Foo foo { 1, 2, 3, 4 }; // call constructor
Foo foo = { 1, 2, 3, 4 }; // call operator=
 

For-each loops - C++11

for (int num : tab)
for (auto num : tab) // avoid type conversion
for (auto &num : tab) // avoid copy
for (const auto &num : tab) // read-only
For-each loops don't work with array decayed to pointer (fixed or dynamic)

std::r­and()

#include <cstdlib>
#include <ctime>
std::stand(static_cast<unsigned int>(std::time(nullptr))); // seed with time
std::rand(); // [0, RAND_MAX]

// [min, max]
return min + (std::rand()%(max-min+1))
//better
static constexpr double fraction {1.0/(RAND_MAX+1.0)};
return min + static_cast<int>((max-min+1.0)*(std::rand()*fraction))
% is biased towards low numbers

Input validation with std::cin

// extraneous input
std::cin.ignore(32767, '\n'); // clears buffer

// extraction failure
if (std::cin.fail()) { // type or overflow
    std::cin.clear(); // back to normal mode
    std::cin.ignore(32767, '\n');
}

// switch-like validation
int x {};
do {
    std::cin >> x;
} while (x<0);

std::cerr and assert

#include <cstdlib> // for exit
std::cerr << "Error message";
exit(1);

#include <cassert>
assert(x==0); // combines cerr and exit
assert(x==0 && "Error message");
// check at compile-time
static_assert(x==0, "Error message"); // C++11

Operator overlo­ading

int m_value;
int *m_array=nullptr;

// ret by value (ref to out of scope var)
friend Foo operator+(const Foo &foo, const Foo& bar); 
    
// subscript []
// ret by ref to assign (l-value)
int& operator[](const int idx) 
{ return m_array[idx]; } 
    
// overload int typecast
operator int() const { return m_value; }

// std::cout
std::ostream& operator<<(std::ostream& out, const Foo &foo)
{
    out << m_value;
    return out;
}

// std::cin
std::istream& operator>>(std::istream& in, Foo &foo)
{
    in >> m_value;
    return in;
}

// increment operator as member function
Foo& operator++(); // prefix, ++x
Foo operator++(int) // postfix, x++
{
    Foo tmp(foo);
    // call implicit copy constructor
    // or assignment with tmp = foo
    // but beware of shallow copy

    // increment this
    return tmp; // return by value
}
1) unary op or if modif to left operand
-> member function
no modif, binary as friend or regular one
2) [], =, (), -> as member