Created
April 16, 2019 15:25
-
-
Save horiajurcut/3355abf8e59fcfeb37c4962446207116 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
using String = std::string; | |
class Entity { | |
private: | |
mutable int m_GetCount; | |
int m_Age; | |
String m_Name; | |
public: | |
Entity() | |
: m_GetCount(0), m_Age(-1), m_Name("Unknown") | |
{ | |
} | |
Entity(const String& name) | |
: m_GetCount(0), m_Age(-1), m_Name(name) | |
{ | |
} | |
// explicit Entity(int age) -> disables implicit conversions | |
Entity(int age) | |
: m_GetCount(0), m_Age(age), m_Name("Unknown") | |
{ | |
} | |
const String& GetName() const | |
{ | |
++m_GetCount; | |
return m_Name; | |
} | |
}; | |
void Function() | |
{ | |
Entity outsideEntity = Entity("Strange Things"); | |
// Here outsideEntity gets destroyed from memory -> stack frame gets destroyed | |
} | |
void PrintEntity(const Entity& entity) | |
{ | |
std::cout << entity.GetName() << std::endl; | |
} | |
struct Vector2 | |
{ | |
float x, y; | |
Vector2(float x, float y) | |
: x(x), y(y) {} | |
Vector2 Add(const Vector2& other) const | |
{ | |
return Vector2(x + other.x, y + other.y); | |
} | |
Vector2 operator+(const Vector2& other) const | |
{ | |
return Add(other); | |
} | |
Vector2 Multiply(const Vector2& other) const | |
{ | |
// return (*this) * other; -> Could do this and dereference the pointer this | |
return operator*(other); | |
} | |
Vector2 operator*(const Vector2& other) const | |
{ | |
return Vector2(x * other.x, y * other.y); | |
} | |
bool operator==(const Vector2& other) const | |
{ | |
return x == other.x && y == other.y; | |
} | |
bool operator!=(const Vector2& other) const | |
{ | |
// return !operator==(other); -> this also works | |
return !(*this == other); | |
} | |
}; | |
std::ostream& operator<<(std::ostream& stream, const Vector2& other) | |
{ | |
stream << "Vector2(" << other.x << ", " << other.y << ")"; | |
return stream; | |
} | |
int main() | |
{ | |
std::cout << "Classes in C++" << std::endl; | |
// STACK ALLOCATION | |
// Create an instance of Entity on the STACK | |
// It exists only in the current scope | |
Entity entityA; // Created an instance of Entity using the default constructor | |
std::cout << entityA.GetName() << std::endl; | |
Entity entityB("Thanos"); // Created an instance of Entity using the second constructor | |
std::cout << entityB.GetName() << std::endl; | |
Entity entityC = Entity("Captain America"); // Another way of instantiating an Entity | |
std::cout << entityC.GetName() << std::endl; | |
// When we call Function() a stack frame gets created for this function | |
Function(); | |
// Example of how this can fail | |
Entity* e; | |
{ | |
Entity ent = Entity("Evil Entity"); | |
e = &ent; | |
std::cout << ent.GetName() << std::endl; | |
// ent gets destroyed but the pointer lives on | |
// This is why we might want to allocate memory on the heap for ent | |
} | |
// HEAP ALLOCATION | |
Entity* eheap; | |
{ | |
Entity* neheap = new Entity("Heap Entity"); // new returns the location on the HEAP where this entity has been allocated | |
eheap = neheap; | |
std::cout << neheap->GetName() << std::endl; | |
} | |
std::cout << eheap->GetName() << std::endl; | |
delete eheap; | |
// THE NEW KEYWORD | |
int* heapInt = new int; | |
int* heapIntArray = new int[50]; // 4 bytes (int) * 50 = 200 bytes | |
delete heapInt; | |
delete[] heapIntArray; // delete heapIntArray is undefined behaviour | |
Entity* entityArray = new Entity[50]; | |
delete[] entityArray; | |
// USUALLY new calls malloc | |
// Entity* entity = new Entity(); -> allocates memory and calls the Entity constructor | |
// Entity* entity = (Entity*)malloc(sizeof(Entity)); -> purely allocates memory | |
// delete entity; -> free up memory and call destructor | |
// free(entity); -> free up memory | |
// IMPLICIT CONVERSIONS | |
Entity a("Cherno"); | |
Entity b(22); | |
Entity c = 22; // Implicit conversion and construction -> There is a constructor that takes in an int and creates an Entity | |
// Entity d = "Cherno"; -> C++ is only allowed to do one implicit conversion, this doesn't work | |
Entity d = String("Cherno"); | |
// More implicit conversion and construction magic | |
PrintEntity(22); | |
PrintEntity(String("Horia")); | |
PrintEntity(Entity("Jimmy")); | |
// EXPLICIT keyword -> disables the implicit conversions; used with a constructor | |
// OPERATOR OVERLOADING | |
Vector2 position = Vector2(4.0f, 5.0f); | |
Vector2 speed(0.5f, 1.5f); | |
Vector2 powerup = Vector2(1.2f, 3.2f); | |
Vector2 result = position.Add(speed.Multiply(powerup)); | |
Vector2 opResult = position + speed * powerup; | |
std::cout << opResult << std::endl; | |
std::cin.get(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment