aboutsummaryrefslogtreecommitdiffstats
path: root/src/lesson21_oop_inherit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lesson21_oop_inherit.cpp')
-rw-r--r--src/lesson21_oop_inherit.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/lesson21_oop_inherit.cpp b/src/lesson21_oop_inherit.cpp
new file mode 100644
index 0000000..2bb4409
--- /dev/null
+++ b/src/lesson21_oop_inherit.cpp
@@ -0,0 +1,121 @@
+//============================================================================
+// Author : Sven Göthel
+// Copyright : 2024 Göthel Software e.K.
+// License : MIT
+// Description : C++ Lesson 2.1 OOP (simple class inheritance w/o virtual functions)
+//============================================================================
+
+#include <limits>
+#include <string>
+#include <memory>
+#include <cassert>
+#include <iostream>
+
+class creature_t {
+ protected:
+ typedef std::string (*to_string_func_t)(const creature_t&) noexcept;
+
+ private:
+ to_string_func_t m_to_string;
+ int m_init_lifetime_left;
+ int m_lifetime_left;
+
+ protected:
+ /** Custom constructor (ctor) */
+ creature_t(to_string_func_t to_string_func, int lifetime_left) noexcept
+ : m_to_string(to_string_func),
+ m_init_lifetime_left(lifetime_left),
+ m_lifetime_left(lifetime_left) {}
+
+ /** Copy ctor */
+ creature_t(const creature_t& o) noexcept = default;
+
+ public:
+ /** Destructor (dtor) */
+ ~creature_t() noexcept = default;
+
+ int total_lifetime() const noexcept { return m_init_lifetime_left; }
+ int lifetime_left() const noexcept { return m_lifetime_left; }
+ int age() const noexcept { return total_lifetime() - lifetime_left(); }
+ bool alive() const noexcept { return lifetime_left() > 0; }
+ std::string lifesign() const noexcept { return alive() ? "☀" : "✝"; }
+
+ /** Subtract given years of life and return whether there is lifetime left */
+ bool tick(int years) noexcept {
+ if( m_lifetime_left > years ) {
+ m_lifetime_left -= years;
+ return true;
+ } else {
+ m_lifetime_left = 0;
+ return false;
+ }
+ }
+
+ std::string to_substring() const noexcept {
+ return "age "+std::to_string(age())+"/"+std::to_string(total_lifetime());
+ }
+
+ std::string to_string() const noexcept {
+ return m_to_string(*this);
+ }
+};
+
+std::ostream& operator<<(std::ostream& out, const creature_t& v) {
+ return out << v.to_string();
+}
+
+class plant_t : public creature_t {
+ public:
+ /** Custom constructor (ctor) */
+ plant_t(int lifetime_left) noexcept
+ : creature_t(to_string_impl, lifetime_left) {}
+
+ /** Copy ctor */
+ plant_t(const plant_t& o) noexcept
+ : creature_t(o) { }
+
+ private:
+ static std::string to_string_impl(const creature_t& t) noexcept {
+ return "plant"+t.lifesign()+"["+t.to_substring()+"]";
+ }
+};
+
+class animal_t : public creature_t {
+ public:
+ /** Custom constructor (ctor) */
+ animal_t(int lifetime_left) noexcept
+ : creature_t(to_string_impl, lifetime_left) {}
+
+ /** Copy ctor */
+ animal_t(const creature_t& o) noexcept
+ : creature_t(o) { }
+
+ private:
+ static std::string to_string_impl(const creature_t& t) noexcept {
+ return "animal"+t.lifesign()+"["+t.to_substring()+"]";
+ }
+};
+
+int main(int, char*[]) {
+ plant_t p1(3);
+ animal_t a1(80);
+
+ std::cout << "00.p1 = " << p1 << std::endl;
+ std::cout << "00.a1 = " << a1 << std::endl;
+
+ creature_t& c1p1 = p1, &c2a1 = a1;
+ std::cout << "00.c1p1 = " << c1p1 << std::endl;
+ std::cout << "00.c2a1 = " << c2a1 << std::endl;
+
+ p1.tick(1);
+ a1.tick(1);
+ std::cout << "01.p1 = " << p1 << std::endl;
+ std::cout << "01.a1 = " << a1 << std::endl;
+
+ p1.tick(2);
+ a1.tick(79);
+ std::cout << "03.p1 = " << p1 << std::endl;
+ std::cout << "79.a1 = " << a1 << std::endl;
+
+ return 0;
+}