Skip to content

Instantly share code, notes, and snippets.

@h4k1m0u
Last active February 27, 2025 22:13
Show Gist options
  • Save h4k1m0u/60fa85175d7987056e10a7b8b6f539d6 to your computer and use it in GitHub Desktop.
Save h4k1m0u/60fa85175d7987056e10a7b8b6f539d6 to your computer and use it in GitHub Desktop.

C++ syntax

List initialization

Advantage: Doesn't allow narrowing, i.e. the following throws an error:

int i {2.0f};

Direct and copy initialization

Advantage: Doesn't create a copy (practical for objects):

T a(b); // direct initialization
T a = b; // copy initialization (temporary object created from b)
T a = T(b); // similar to previous line

const keyword

Passing arguments by constant reference

Alternative to passing by value because:

  • Reference => Avoids making a copy, unlike pass by value.
  • Constant => Cannot by modified, like pass by value.
void foo(const string& s);

Const methods

It guarantees that the object it is being invoked on cannot be changed.

class MyClass {
public:
    int fct(int var) const;
}

Const field member

It deletes the assignment operator, unless the field is made static.

Linkage

  • Constants at file scope (global) or namespace scope have internal linkage (in constrast with variables which have external linkage).
  • Internal linkage means it can be seen only from within its translation unit (like with static keyword at file scope)

constexpr keyword

  • A constrexpr class field must be static, because a constexpr is evaluated at compile time, whereas a non-static field member is not initialized till runtime (when instance created).
  • A static constexpr can be defined in header (in constrast to static const), because it's implicitely an inline variable.

inline keyword

Inline functions

  • When the execution time of a small function is less than the switching time, the inline keyword tells the compiler to insert the code of the inline function where it is called.
  • They can be defined in class header without multiple definitions error being reported by linker.

Inline class fields

  • Allows a static field member to be initialized in header without reporting multiple definitions error (from each translation unit it's included in).

Getter and setters

  • To avoid as much as possible for a better encapsulation.

Declaring a variable inside a loop

  • It's encouraged for primitive types as it reduces their scope while the variable is only allocated once.
  • For objects, the constructor and the destructor are called in every iteration.

Functors

  • Functors (function object) are classes which implement operator().
  • They operate like functions, but are capable of storing data in member variables.
  • Used for sorting std::vectors and for calculating the minimum and the maximum.
class Accumulator {
private:
    int m_counter{0};
public:
    Accumulator() {}
    int operator() (int i) {
        return (m_counter += i);
    }
};

int main() {
    Accumulator acc;
    std::cout << acc(10) << '\n'; // prints 10
    std::cout << acc(20) << '\n'; // prints 30
 
    return 0;
}

Constructor and destructor

Base constructor in initialization list

The constructor of the base class can be called in a derived class inside the member initialization list.

class Base {
private:
    int m_id;
public:
    Base(int id): m_id{id} {}
}

class Derived: public Base {
private:
    double m_cost;
public:
    Derived(int id, double cost):
        Base(id), // note the call to Base's constructor
        m_cost{cost}
    {
    }
}

Virtual destructor

When the static type of an object is different from its dynamic one (polymorphism), the destructor must be virtual or else the derived part won't be freed (source).

Pointers

int i = 3;
int* p = new int; // dynamic allocation of pointer (on the heap)
p = &i;
delete p; // release storage space allocated with new

Smart pointers

  • See this introductory youtube video.
  • Introduced in C++11, and are preferred to raw pointers.
  • Object that wraps a raw pointer to manage its lifetime (i.e. avoids memory leaks).
  • The wrapped pointer will be deleted once out of scope.
  • Unique pointer:
    • Cannot be copied.
    • Initialize with make_unique() to handle exceptions.

Vectors

std::vector<Type> allocates its Type elements on the heap (like a pointer or an array), and its header on the stack.

Passing functions as arguments

  • Same as function pointers in C (see example below).
  • There's a more convenient way to pass functions:
#include <functional>

int operation(int a, int b, std::function<int (int, int)> f) { return f(a, b) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment