File structure
Source files use the extension .cpp
, header files use .h
(or rarely .hpp
).
Declarations belong in header files, definitions belong in source files. Identifiers can be declared more than once (which allows header files to be included multiple times without error), but can be defined at most once.
Source files are compiled individually, with no knowledge of the contents of other files. Header files allow identifiers to be used from other files, by allowing the required declarations to be included at the top of every file. Header files also prevent the issue of forward declarations in the same file.
Source files are individually compiled into object files, and then those object files are linked together into an executable.
Types
Fundamental integral types
All types are signed by default, unless prefixed with unsigned
.
Type | Width |
---|---|
char |
at least 8 |
short |
at least 16 |
int |
at least 16 |
long |
at least 32 |
long long |
at least 64 |
int
is the optimal integer size on the target platform.
bool
is an integer type that can only hold the values 0
and 1
.
wchar_t
is a distinct type that is large enough to represent any supported character code point. This is 16 bits on Windows (uses UTF-16) and 32 bits on Linux (uses UTF-32). The types char8_t
, char16_t
, and char32_t
also exist on all platforms.
Fixed-width integral types
These must be included first with #include <cstdint>
.
Signed | Unsigned | Width |
---|---|---|
int8_t |
uint8_t |
exactly 8 |
int16_t |
uint16_t |
exactly 16 |
int32_t |
uint32_t |
exactly 32 |
int64_t |
uint64_t |
exactly 64 |
size_t
is the optimal type for indexing into an array.
Strings
These must be included first with #include <string>
.
All strings extend std::basic_string<T>
. std::wstring
is a Unicode string, using wchar_t
as the character type. std::string
is an ASCII string, using char
as the character type.
Constants
There are a few different meanings of constant in C++:
const
marks a value as immutable, preventing it from being modified.constexpr
marks a value as being calculated at compile-time.* const
indicates a constant pointer. The data behind the pointer can be modified, but the pointer itself cannot.fn() const
marks a constant method, preventing class members from being modified.
const int v = 2*3; // value is immutable. constexpr int v = 2*3; // value is calculated at compile time. int fibonacci(const int n); // function will not modify its argument. int List::size() const; // method will not modify any members.
Functions
A function can be a member of a class. The class name is part of the signature.
char& String::operator[](int index);
Collections
Vector
A resizeable homogeneous array, defined as std::vector
in the vector
library.
vector<unsigned int> list = { 1, 2, 3 }; list.at(0); list[0]; list.size();
Map
Hashmaps are provided as std::unordered_map
in the unordered_map
library.
unordered_map<string, string> registry = {}; registry.insert({"key", "value"}); string v = registry["key"];
References
int x = 1; // x is 1 int& r = x; // r is a reference to x r = 2; // x is 2
Passing by reference
Values can be passed by reference by adding a &
character as a suffix to the argument in the function signature:
#include <iostream> #include <vector> using namespace std; int sum_list(vector<int>& list) { int sum = 0; for (int element : list) { sum += element; } return sum; } int main() { vector<int> list = { 1, 2, 3 }; cout << sum_list(list) << "\n"; }
rvalue reference
An rvalue (or ‘temporary’) is a value that is about to be destroyed. An rvalue reference, identified by T&&
, refers to an rvalue that can be modified. It allows a value to be passed to a function with move semantics, rather than the default behaviour of copying the value and then immediately deleting the original instance.
int&& a = 5;
Pointers
Creating a pointer
Pointers are created with the &
address-of syntax.
int x = 2; int* p = &x; *p = 3;
Pointer arithmetic
A pointer can be advanced to point to the following item of a sequence with the ++
operator.
Null pointer
The null pointer is called nullptr
, and represents the absence of a value. It is used as the terminator for null-terminated strings.
There is only one nullptr
shared by all pointer types.
Allocation
Objects can be allocated onto the heap with new
, and deallocated with delete
.
int* values = new int[10]; delete values;
Classes
Class members are private by default.
class Stack { private: uint8_t p; uint8_t mem[256]; public: Stack(); }; Stack::Stack() : p{0}, mem{} { }