summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--inheritance.cpp57
-rw-r--r--inheritance.hpp40
-rw-r--r--makefile16
-rw-r--r--memory-allocation.cpp9
-rw-r--r--memory-classes.cpp53
-rw-r--r--memory-classes.hpp23
-rw-r--r--namespaces.cpp37
-rw-r--r--namespaces.hpp21
-rw-r--r--polymorphism.cpp46
-rw-r--r--references.cpp44
-rw-r--r--simple-classes.cpp59
-rw-r--r--simple-classes.hpp23
-rw-r--r--template.cpp23
14 files changed, 452 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..378eac2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/inheritance.cpp b/inheritance.cpp
new file mode 100644
index 0000000..8534769
--- /dev/null
+++ b/inheritance.cpp
@@ -0,0 +1,57 @@
+#include "inheritance.hpp"
+
+container::container(std::size_t max_size_) : max_size(max_size_) {
+ // intialize storage
+ m_storage = new int[max_size];
+}
+
+container::~container() {
+ if (m_storage != nullptr)
+ delete m_storage;
+}
+
+void lifo::add(int v) {
+ push(v);
+}
+
+int lifo::get() {
+ return pop();
+}
+
+void lifo::push(int v) {
+ if (m_top >= max_size)
+ return;
+
+ m_storage[m_top++] = v;
+}
+
+int lifo::pop() {
+ if (m_top <= 0)
+ return 0;
+
+ return m_storage[--m_top];
+}
+
+
+void fifo::add(int v) {
+
+}
+
+int fifo::get() {
+ return 0;
+}
+
+
+int main(int argc, char *argv[]) {
+
+ container *c = new lifo(2);
+
+ c->add(1);
+ c->add(2);
+
+ lifo *b = static_cast<lifo *> (c);
+
+ b->push(2);
+
+ delete c;
+}
diff --git a/inheritance.hpp b/inheritance.hpp
new file mode 100644
index 0000000..6fbc48e
--- /dev/null
+++ b/inheritance.hpp
@@ -0,0 +1,40 @@
+#include <cstddef>
+
+class container {
+public:
+ const std::size_t max_size;
+
+ container() = delete;
+ container(std::size_t max_size);
+ virtual ~container();
+
+ virtual void add(int v) = 0;
+ virtual int get() = 0;
+
+protected:
+ int *m_storage = nullptr;
+};
+
+
+class lifo : public container {
+public:
+ lifo(std::size_t max_size) : container(max_size) {}
+
+ void add(int v) override;
+ int get() override;
+
+ void push(int v);
+ int pop();
+
+private:
+ unsigned m_top = 0;
+};
+
+
+class fifo : public container {
+ fifo(std::size_t max_size) : container(max_size) {}
+
+ void add(int v) override;
+ int get() override;
+};
+
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..823954d
--- /dev/null
+++ b/makefile
@@ -0,0 +1,16 @@
+CPP := g++
+CPP_ARGS := -Wall -g -I.
+LD_ARGS :=
+
+BINARIES := $(patsubst %.cpp, build/%, $(wildcard *.cpp))
+
+.PHONY: all
+all: $(BINARIES)
+
+.PHONY: clean
+clean:
+ - rm $(BINARIES)
+
+build/%: %.cpp
+ - mkdir -p build
+ - $(CPP) $(CPP_ARGS) $< -o $@ $(LD_ARGS)
diff --git a/memory-allocation.cpp b/memory-allocation.cpp
new file mode 100644
index 0000000..83d7eda
--- /dev/null
+++ b/memory-allocation.cpp
@@ -0,0 +1,9 @@
+int main(int argc, char *argv[]) {
+ // int *hello = (int) malloc(10 * sizeof(int));
+ int *hello = new int[10];
+
+ // free(hello)
+ delete hello;
+
+ return 0;
+}
diff --git a/memory-classes.cpp b/memory-classes.cpp
new file mode 100644
index 0000000..19d17e9
--- /dev/null
+++ b/memory-classes.cpp
@@ -0,0 +1,53 @@
+#include "memory-classes.hpp"
+
+#include <iostream>
+
+
+lifo::lifo(std::size_t max_size_) : max_size(max_size_) {
+ m_storage = new int[max_size];
+}
+
+lifo::~lifo() {
+ if (m_storage != nullptr)
+ delete m_storage;
+}
+
+void lifo::push(int v) {
+ if (m_top >= max_size)
+ return;
+
+ m_storage[m_top++] = v;
+}
+
+int lifo::pop() {
+ if (m_top <= 0)
+ return 0;
+
+ return m_storage[--m_top];
+}
+
+
+int main(int argc, char *argv[]) {
+
+ // the lifo allocates a memory buffer
+ lifo stack(5);
+
+ stack.push(1);
+ stack.push(2);
+ stack.push(3);
+ stack.push(4);
+ stack.push(5);
+
+ std::cout << stack.pop() << std::endl;
+ std::cout << stack.pop() << std::endl;
+ std::cout << stack.pop() << std::endl;
+ std::cout << stack.pop() << std::endl;
+ std::cout << stack.pop() << std::endl;
+
+ return 0;
+
+ // here, when the scope ends the stack object is destroyed
+ // as it goes *out of scope*, and so the destructor is called
+ // which frees the memory
+
+}
diff --git a/memory-classes.hpp b/memory-classes.hpp
new file mode 100644
index 0000000..8d9b31d
--- /dev/null
+++ b/memory-classes.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <cstddef>
+
+// a very crappy lifo class
+class lifo {
+public:
+ const std::size_t max_size;
+
+ // no default constructor
+ lifo() = delete;
+
+ lifo(std::size_t max_size);
+ // this is a destructor
+ ~lifo();
+
+ void push(int v);
+ int pop();
+
+private:
+ unsigned m_top = 0;
+ int *m_storage = nullptr;
+};
diff --git a/namespaces.cpp b/namespaces.cpp
new file mode 100644
index 0000000..2e93b61
--- /dev/null
+++ b/namespaces.cpp
@@ -0,0 +1,37 @@
+#include <iostream>
+
+#include "namespaces.hpp"
+
+// to access a namespace the notation is `<namespace>::<element>'
+// it is possible to create nested namespaces (!) `<nsA>::<nsB>::elm'
+int math::dot(math::vec3i v, math::vec3i w) {
+ return v.x * w.x + v.y * w.y + v.z * w.z;
+}
+
+// alternatively (but not recommended) we can enclose the code
+// in a namespace declaration
+namespace math {
+ double dot(vec3d v, vec3d w) {
+ return v.x * w.x + v.y * w.y + v.z * w.z;
+ }
+}
+
+
+int main(int argc, char *argv[]) {
+
+ math::vec3i a = { 1, 2, 3 };
+ math::vec3i b = { 1, 2, 3 };
+ std::cout << math::dot(a, b) << std::endl;
+
+ // it is also possible to specify to implicitly
+ // always use the namespace in a scope
+ {
+ using namespace math;
+
+ vec3d c = { .5, .2, 11.2 };
+ vec3d d = { .2, .2, 12.3 };
+ std::cout << dot(c, d) << std::endl;
+ }
+
+ return 0;
+}
diff --git a/namespaces.hpp b/namespaces.hpp
new file mode 100644
index 0000000..dc8ef7c
--- /dev/null
+++ b/namespaces.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+// C++ introduces namespaces to separate various things
+// into logical blocks
+namespace math {
+ struct vec3i {
+ int x;
+ int y;
+ int z;
+ };
+
+ struct vec3d {
+ double x;
+ double y;
+ double z;
+ };
+
+
+ int dot(vec3i v, vec3i w);
+ double dot(vec3d v, vec3d w);
+}
diff --git a/polymorphism.cpp b/polymorphism.cpp
new file mode 100644
index 0000000..89f5005
--- /dev/null
+++ b/polymorphism.cpp
@@ -0,0 +1,46 @@
+#include <iostream>
+
+// here we have a bunch of structures to represent
+// 3 dimensional math vectors, one with integer values
+// and another with double precision floating point values
+struct vec3i {
+ int x;
+ int y;
+ int z;
+};
+
+struct vec3d {
+ double x;
+ double y;
+ double z;
+};
+
+// and we define the dot product operation
+int dot(vec3i v, vec3i w) {
+ return v.x * w.x + v.y * w.y + v.z * w.z;
+}
+
+// notice that this function is also called dot() like the one above
+// the difference is in the return value and the arguments
+// this functions is said to *overload* the one before
+double dot(vec3d v, vec3d w) {
+ return v.x * w.x + v.y * w.y + v.z * w.z;
+}
+
+
+int main(int argc, char *argv[]) {
+
+ vec3i a = { 1, 2, 3 };
+ vec3i b = { 1, 2, 3 };
+ // lets use our data and functions
+ std::cout << dot(a, b) << std::endl;
+
+ vec3d c = { .5, .2, 11.2 };
+ vec3d d = { .2, .2, 12.3 };
+
+ // notice how the compiler recognizes the type of the argument
+ // and calls the correct dot() function
+ std::cout << dot(c, d) << std::endl;
+
+ return 0;
+}
diff --git a/references.cpp b/references.cpp
new file mode 100644
index 0000000..be40a50
--- /dev/null
+++ b/references.cpp
@@ -0,0 +1,44 @@
+#include <iostream>
+
+// a basic new feature of C++ are references, they are like
+// pointers, but they *can't* be null, which btw in c++ is `nullptr'
+
+
+// here is a typical C example to use pointers
+void inc_ptr_val(int *v) {
+ // check that v is not null
+ if (v == nullptr) {
+ return;
+ }
+
+ // increment where v points
+ (*v)++;
+}
+
+// and here is a new (better) version
+void inc_ref_val(int& v) {
+ // no need to check
+ // no need to dereference
+ v++;
+}
+
+// an interesting twist is that we can now have const references
+// which is like a C "T const * const" ie read only reference
+// and is used to not copy big things on the stack
+bool is_hello(const std::string& s) {
+ // s cannot be changed, only read
+ return s == "hello";
+}
+
+
+int main(int argc, char *arg[]) {
+
+ int hello = 10;
+ std::cout << hello << std::endl;
+
+ inc_ptr_val(&hello);
+ std::cout << hello << std::endl;
+
+ inc_ref_val(hello);
+ std::cout << hello << std::endl;
+}
diff --git a/simple-classes.cpp b/simple-classes.cpp
new file mode 100644
index 0000000..c21837b
--- /dev/null
+++ b/simple-classes.cpp
@@ -0,0 +1,59 @@
+#include "simple-classes.hpp"
+
+#include <iostream>
+
+
+// implementation for the default constructor
+// math::vec3i::vec3i() {
+// x = 0;
+// y = 0;
+// z = 0;
+// }
+
+// here is a modern implementation that
+// uses a C++11 feature called `member initializers'
+math::vec3i::vec3i() : x(0), y(0), z(0) {
+ // does nothing special
+}
+
+// implementation for the copy constructor, that
+// copies the other object
+math::vec3i::vec3i(const math::vec3i& other) {
+ // in this case we copy only the components
+ x = other.x;
+ y = other.y;
+ z = other.z;
+}
+
+// impl for a custom constructor
+math::vec3i::vec3i(int x_, int y_, int z_) {
+ x = x_;
+ y = y_;
+ z = z_;
+}
+
+
+void math::vec3i::zero() {
+ x = 0;
+ y = 0;
+ z = 0;
+}
+
+int math::vec3i::dot(const vec3i& other) const {
+ return x * other.x + y * other.y + z * other.z;
+}
+
+
+int main(int argc, char *argv[]) {
+
+ // a vector with zeroes
+ math::vec3i v;
+ // a copy of v
+ const math::vec3i u(v);
+ // a vector initialized
+ math::vec3i w(1, 2, 3);
+
+ std::cout << u.dot(w) << std::endl;
+
+ return 0;
+}
diff --git a/simple-classes.hpp b/simple-classes.hpp
new file mode 100644
index 0000000..80743d4
--- /dev/null
+++ b/simple-classes.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+namespace math {
+ // a class is a glorified struct
+ class vec3i {
+ public:
+ // members
+ int x;
+ int y;
+ int z;
+
+ // default constructor
+ vec3i();
+ // copy constructor
+ vec3i(const vec3i& other);
+ // custom constructor
+ vec3i(int x_, int y_, int z_);
+
+ // method
+ void zero();
+ int dot(const vec3i& other) const;
+ };
+}
diff --git a/template.cpp b/template.cpp
new file mode 100644
index 0000000..e67645b
--- /dev/null
+++ b/template.cpp
@@ -0,0 +1,23 @@
+#include <iostream>
+
+template<typename T>
+struct vec3 {
+ T x;
+ T y;
+ T z;
+};
+
+template<typename T>
+int dot(vec3<T> v, vec3<T> u) {
+ return v.x * u.x + v.y * u.y + v.z * u.z;
+}
+
+int main(int argc, char *argv[]) {
+
+ vec3<int> v = {1, 2, 3};
+ vec3<int> u = {1, 2, 3};
+
+ std::cout << dot(v, u) << std::endl;
+
+ return 0;
+}