From 05f2df34290af477b0fee49b75e5f56e1d6c83f9 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sat, 8 Dec 2018 12:58:04 +0100 Subject: Initial commit with kinda crappy unnumbered examples --- .gitignore | 1 + inheritance.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ inheritance.hpp | 40 ++++++++++++++++++++++++++++++++++ makefile | 16 ++++++++++++++ memory-allocation.cpp | 9 ++++++++ memory-classes.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++ memory-classes.hpp | 23 ++++++++++++++++++++ namespaces.cpp | 37 ++++++++++++++++++++++++++++++++ namespaces.hpp | 21 ++++++++++++++++++ polymorphism.cpp | 46 +++++++++++++++++++++++++++++++++++++++ references.cpp | 44 ++++++++++++++++++++++++++++++++++++++ simple-classes.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ simple-classes.hpp | 23 ++++++++++++++++++++ template.cpp | 23 ++++++++++++++++++++ 14 files changed, 452 insertions(+) create mode 100644 .gitignore create mode 100644 inheritance.cpp create mode 100644 inheritance.hpp create mode 100644 makefile create mode 100644 memory-allocation.cpp create mode 100644 memory-classes.cpp create mode 100644 memory-classes.hpp create mode 100644 namespaces.cpp create mode 100644 namespaces.hpp create mode 100644 polymorphism.cpp create mode 100644 references.cpp create mode 100644 simple-classes.cpp create mode 100644 simple-classes.hpp create mode 100644 template.cpp 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 (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 + +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 + + +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 + +// 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 + +#include "namespaces.hpp" + +// to access a namespace the notation is `::' +// it is possible to create nested namespaces (!) `::::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 + +// 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 + +// 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 + + +// 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 + +template +struct vec3 { + T x; + T y; + T z; +}; + +template +int dot(vec3 v, vec3 u) { + return v.x * u.x + v.y * u.y + v.z * u.z; +} + +int main(int argc, char *argv[]) { + + vec3 v = {1, 2, 3}; + vec3 u = {1, 2, 3}; + + std::cout << dot(v, u) << std::endl; + + return 0; +} -- cgit v1.2.1