References
In C++ classes are value types by default, not reference types like in C#.
Passing a class instance by reference to a function in C# is:
// csharp
void Example(Class instance)
{
// changes the original instance
instance.variable = 1;
// this creates a copy
Class instance_copy = instance.Clone();
}
Passing a class instance by reference to a function in C++ is:
// cpp
void Example(Class& instance)
{
// changes the original instance
instance.variable = 1;
// this creates a copy
Class instance_copy = instance;
}
You can also pass a class instance in C++ with a pointer:
// cpp
void Example(Class* instance_ptr)
{
// changes the original instance
instance_ptr->variable = 1;
// changes the original instance
(*instance_ptr).variable = 1;
// this creates a copy
Class instance_copy = *instance_ptr;
}
Memory
Stack:
When creating a variable in C++ it uses the stack by default. Memory on the stack is local to its scope and gets released automatically when the variable goes out of scope.
Heap:
When you want memory to exist outside of the scope it is created in, you must allocate memory for it on the heap.
You can allocate memory on the heap using malloc()
and release it using free()
.
But a better alternative is using auto variable = new Type();
and release it using delete variable;
Leaks:
In C++ heap memory does not automatically free when the application terminates. and in both C++ and C# OpenGL data like buffers and textures in vram also dont automatically free when the application terminates. Generally speaking the os will reclaim unfreed memory when the application terminates, but relying on this is bad practice.
Pointers
Basic:
Raw pointers in C++ work the same as in C#, the syntax is the exact same:
int x = 1;
int* ptr = &x;
int y = *ptr;
it doesnt matter where in a pointer you use a space as it will all work:
int* ptr = &x;
int *ptr = &x;
int*ptr = &x;
Smart:
There are 3 types of smart pointers: std::unique_ptr
std::shared_ptr
std::weak_ptr
, to use them with #include <memory>
Headers
What are they?:
In C# you can acces functions that are in a different .cs
file by just making them both use the same namespace. In C++, its a little bit more complex.
Header files can be seen as an outline of all the functions contained in a .cpp
file.
All code goes in .cpp
files, and then every file has a header .hpp
file with the same exact name which contains all the declerations (names) of your functions.
Using headers help the compiler understand how source files are connected, which is one of the reasons C++ code compiles so very fast compared to C# code.
How are they used?:
You can access code from other files only by using #include "file.h"
at the top of your code. Which will simply copy the entire header to that point.
You can include a header in 2 ways: #include "file.h"
or #include <file.h>
. Using quotes will search the header in your current directory and using angled brackets will search the header in the include directory.
Further Reading:
Public / Private
In C# you can put public or private before any member of a class like so:
class Person
{
public float a;
private float b;
public float c;
}
In C++ you put all public member under public:
and all private members under private:
like so:
class Person
{
public:
float a;
float c;
private:
float b;
}
Lambda Expressions
A lambda expression like in C# is a lambda calculus function. In simple terms it can be described as an inline function.
This is how lambdas in C# look:
// csharp
// single line lambda
var add = (int a, int b) => a + b;
// multi line lambda
var add_and_mult = (int a, int b) =>
{
var x = a + b;
var y = x * 2;
return y;
};
This is how lambdas in C++ look:
// cpp
// single line lambda
auto add = [](int a, int b) { return a + b; };
// multi line lambda
auto add_and_mult = [](int a, int b)
{
auto x = a + b;
auto y = x * 2;
return y;
};
// lambda with explicit return type
auto add = [](int a, int b) -> int
{
return a + b;
};
When using C++ lambda expressions also have the ability to capture variables from their surrounding scope.
Capturing determines how variables from the surrounding scope are made available to inside the lambda.
You determine how do capture variabled based on what you place inside the [ ]
capture brackets.
// cpp
int first = 10;
int second = 20;
// capture all surrounding variabled by value
auto lambda = [=](int a)
{
a = first + second;
first = a; // doesnt change the original
};
// capture all surrounding variabled by reference
auto lambda = [&](int a)
{
a = first + second;
first = a; // changes the original
};
// captures 'int first' by value and 'int second' by reference
auto lambda = [first, &second](int a)
{
a = first + second;
first = a; // doesnt change the original
};
// captures 'int first' by reference and 'int second' by value
auto lambda = [&first, second](int a)
{
a = first + second;
first = a; // changes the original
};
Operator overloading
In C# operator overloading works like this:
// csharp
public static Type operator +(Type a, Type b)
{
return new Type(a.value + b.value);
}
In C# you always need to make an operator overload public
and static
, in C++ you dont.
Also as you can see for C# we use the new
keyword because that makes the object exist on the heap and it returns a type by reference, thats default for C#.
In C++ operator overloading works like this:
// cpp
Type operator +(Type& b)
{
return Type(this->value + b.value);
}
Also as you can see for C++ we dont use the new
keyword because in C++ everything is a value type by default which are on the stack, the new
keyword makes objects on the heap.
Arrays / Lists
Important differences:
- In C# you write
int[] name
, while in C++ you writeint name[]
, it differs where you place the brackets. - In C# arrays are always on the heap and made with
new
, while in C++ arrays are on the stack. - In C#
int[][]
is a jagged array while in C++int[][]
is a multidimensional array. - In C++ a list is called a vector (yes thats really confusing).
In C# you use arrays like so:
// csharp
// simple array
int[] array = new int[8]; // create
int value = array[0]; // index
// multidimensional array
int[,] array = new int[8, 8]; // create
int value = array[0, 0]; // index
// jagged array (array of arrays)
int[][] array = new int[8][]; // create
int value = array[0][0]; // index
In C++ you use arrays like so:
// cpp
// simple array
int array[8]; // create
int value = array[0] // index
// multidimensional array
int array[8][8]; // create
int value = array[0][0]; // index
In C# you use lists like so:
// csharp
// create list
List<int> list = new List<int>();
// get length of list
int length = list.Count;
// add to list
list.Add(4);
// remove third element from list:
list.RemoveAt(2);
// index list
int value = list[0];
// clear list
list.Clear();
In C++ you use lists (called vectors in c++) like so:
// cpp
// create vector
vector<int> vector;
// get length of vector
int length = vector.size();
// add to vector
vector.push_back(4);
// remove third element from vector
vector.erase(vector.begin() + 2);
// index vector
int value = vector[0];
// clear vector
vector.clear();
Generics / Templates
In C# you create generics like so:
// csharp
// generic function
void Print<T>(T value)
{
Console.WriteLine("value: " + value);
}
// generic function with multiple parameters
void Print<T1, T2>(T1 a, T2 b)
{
Console.WriteLine("a: " + a + " b: " + b);
}
// generic class
class Box<T>
{
T value;
}
In C++ you create generics like so:
// cpp
// generic function
template <typename T>
void Print(T value)
{
cout << "value: " << value;
}
// generic function with multiple parameters
template <typename T1, typename T2>
void Print(T1 a, T2 b)
{
cout << "a: " << a << " b: " << b;
}
// generic class
template <typename T>
class Box
{
T value;
};
Strings
In C# you use strings like so:
// csharp
// creating a string
string hello = "hello";
// combining strings
string combined = hello + "world";
// comparing strings
bool test = ("apple" == "orange");
// number to string
int age = 22;
string message = age.ToString() + " years old";
// get length of string
string test = "test";
int length = test.Length;
// indexing a string
string test = "test";
char index = test[0];
In C++ you use strings like so:
// cpp
// creating a string
string hello = "hello"; // c++ style
char hello[] = "hello"; // plain c style
char* hello = "hello"; // plain c style
// combining strings
string combined = hello + "world";
// comparing strings
bool test = ("apple" == "orange");
// number to string
int age = 22;
string message = to_string(age) + " years old";
// get length of string
string test = "test";
int length = test.length();
// indexing a string
string test = "test";
char index = test[0];