online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include "Clock.h" extern void appl(IClock&); int main() { std::cout.setf(std::ios::boolalpha); Clock c{}; appl(c); }
#include <iostream> #define SHOW(...)\ (void)(std::cout << __FILE__ << ':' << __LINE__ << '\t'\ << #__VA_ARGS__ << " --> " << (__VA_ARGS__)\ << std::endl) #include "IClock.h" void appl(IClock& c) { SHOW(c); c.TickUp(); SHOW(c); c.TickUp(); SHOW(c); c.TickUp(); SHOW(c); c.Set(0, 0, 58); SHOW(c); c.TickUp(); SHOW(c); c.TickUp(); SHOW(c); c.TickUp(); SHOW(c); c.Set(0, 59, 58); SHOW(c); c.TickUp(); SHOW(c); c.TickUp(); SHOW(c); c.TickUp(60); SHOW(c); c.TickUp(600); SHOW(c); }
#ifndef ICLOCK_H #define ICLOCK_H #include <iosfwd> class IClock { public: virtual ~IClock() =default; virtual void Set(int, int, int) =0; virtual void TickUp(int = 1) =0; virtual std::ostream& Print(std::ostream&) const =0; }; inline std::ostream& operator<<(std::ostream& lhs, const IClock& rhs) { return rhs.Print(lhs); } #endif
#ifndef CLOCK_H #define CLOCK_H #include <iosfwd> #include <cstring> #include <iostream> #include "IClock.h" #include "LimitCounter.h" #include "OverflowCounter.h" class Clock : public IClock { LimitCounter hours_; OverflowCounter minutes_; OverflowCounter seconds_; public: Clock(int hours = 0, int minutes = 0, int seconds = 0) : hours_{24} , minutes_{60, hours_} , seconds_{60, minutes_} { Set(hours, minutes, seconds); } Clock(const Clock&) =delete; // copy c'tor Clock& operator=(const Clock&) =delete; // copy assignment Clock(Clock&&) =delete; // move c'tor Clock& operator=(Clock&&) =delete; // move assignment virtual void Set(int hours, int minutes, int seconds) override { hours_.SetValue(hours); minutes_.SetValue(minutes); seconds_.SetValue(seconds); } virtual void TickUp(int seconds) override { seconds_.Count(seconds); } virtual std::ostream& Print(std::ostream&) const override; }; #endif
#include "Clock.h" #include <iostream> #include <iomanip> std::ostream& Clock::Print(std::ostream& s) const { std::ostream os{s.rdbuf()}; os.fill('0'); os << std::setw(2) << hours_.GetValue() << ':' << std::setw(2) << minutes_.GetValue() << ':' << std::setw(2) << seconds_.GetValue(); return s; }
#ifndef ICOUNTER_H #define ICOUNTER_H class ICounter { public: virtual ~ICounter() =default; virtual void Count() =0; virtual void Reset() =0; }; #endif
#ifndef COUNTER_H #define COUNTER_H #include "ICounter.h" template<typename Details> class CounterBase : public ICounter, private Details { private: int value_{}; const int max_value_{}; using Details::WillOverflow; using Details::WillReset; using Details::HasOverflowed; using Details::HasResetted; public: CounterBase(int max_value) : value_{0} , max_value_{max_value} {} CounterBase(int max_value, ICounter& details_arg) : Details{details_arg} , value_{0} , max_value_{max_value} {} void SetValue(int value) { value_ = value; } int GetValue() const { return value_; } void Count(int amount); virtual void Count() override final; virtual void Reset() override final; }; template<typename Details> void CounterBase<Details>::Count(int amount) { while (amount-- > 0) { Count(); } } template<typename Details> void CounterBase<Details>::Count() { if (++value_ >= max_value_) { WillOverflow(); value_ = 0; HasOverflowed(); } } template<typename Details> void CounterBase<Details>::Reset() { WillReset(); value_ = 0; HasResetted(); } class LimitCounter_Details { protected: void WillOverflow() {} void WillReset() {} void HasOverflowed() {} void HasResetted() {} }; using LimitCounter = CounterBase<LimitCounter_Details>; #endif
#ifndef OVERFLOW_COUNTER_H #define OVERFLOW_COUNTER_H #include "LimitCounter.h" class OverflowCounter_Details : protected LimitCounter_Details { ICounter& next_counter_; protected: OverflowCounter_Details(ICounter& next_counter) : LimitCounter_Details{} , next_counter_{next_counter} {} void HasOverflowed() { next_counter_.Count(); } void HasResetted() { next_counter_.Reset(); } }; using OverflowCounter = CounterBase<OverflowCounter_Details>; #endif
clock-6x: g++ -std=c++14 *.cpp -o $@ run: clock-6x ./clock-6x clean: -rm -f *.o a.out core clock-6x zip: zip ../clock-6x.zip *.txt *.cpp *.h
Fill extension points via Template Base class --------------------------------------------- Compared to the traditional "template methode pattern" (according to the name chosen by the authors of the widely known "GoF-Book"), which is filling extension points by overriding inherited member functions in derived classes, an alternative technique is shown here: It is based on calling member functions from a base class which is specified via a template argument, so that different base classes can be used for different needs. In the past this has sometimes been called "inverted template method pattern" but meanwhile is more often called "policy based design". ----------------------------------------------------------------- NOTE: Applying this to the `LimitCounter` / `OverflowCounter` example is a little bit more complicated as the simplest possible form. Read on, it will be explained now. ----------------------------------------------------------------- TBD: describe the purpose of the `Details` class TBD: describe the initialization problem

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue