A simple stop watch which I want to extendSimple stop watchStop Watch applicationStop Watch Application 2.0A thread-safe stop watch utility classTimer stop watch in AngularJSA low tech approach to measuring game speedSimple timer start and stop from consoleExtremely simple timer class in C++A simple Java class for implementing code stop watchesA simple Java class for implementing code stop watches - follow-up

Why is transplanting a specific intact brain impossible if it is generally possible?

Acceptable to cut steak before searing?

How to mark beverage cans in a cooler for a blind person?

Visa National - No Exit Stamp From France on Return to the UK

Why isn’t SHA-3 in wider use?

CTCI Chapter 1 : Palindrome Permutation

Three legged NOT gate? What is this symbol?

Is there a way to unplug the Raspberry pi safely without shutting down

What game uses dice with sides powers of 2?

In SQL Server, why does backward scan of clustered index cannot use parallelism?

Should I ask for permission to write an expository post about someone's else research?

Can the ground attached to neutral fool a receptacle tester?

What does "sardine box" mean?

On the Rømer experiments and the speed if light

Is it legal for a company to enter an agreement not to hire employees from another company?

What gave Harry Potter the idea of writing in Tom Riddle's diary?

Is it okay for a ticket seller to grab a tip in the USA?

Understanding the point of a kölsche Witz

Sign changes after taking the square root inequality. Why?

How can I solve for the intersection points of two ellipses?

Am I overreacting to my team leader's unethical requests?

create a tuple from pairs

Does this Foo machine halt?

How do some PhD students get 10+ papers? Is that what I need for landing good faculty position?



A simple stop watch which I want to extend


Simple stop watchStop Watch applicationStop Watch Application 2.0A thread-safe stop watch utility classTimer stop watch in AngularJSA low tech approach to measuring game speedSimple timer start and stop from consoleExtremely simple timer class in C++A simple Java class for implementing code stop watchesA simple Java class for implementing code stop watches - follow-up






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2












$begingroup$


I am making a very simple stopwatch functionality as below.



New will start the timer.

Pause will suspend the watch.

Start will restart again.

Session will return the duration.



#include<chrono>
#include<vector>

class Timer
using cppTimer = std::chrono::high_resolution_clock;
using seconds = std::chrono::seconds;
std::vector< int64_t > mvSession;
cppTimer::time_point mtpNow;
cppTimer::time_point mtPause;
seconds mtRestart;
bool mbIsPause;
public:

enum Units
sec,
min,
hrs,
end
;

Timer() noexcept: mbIsPause(false), mtRestart ,mvSession(3)


inline void Now() noexcept
mtpNow = cppTimer::now();
mbIsPause = false;
mtRestart = seconds(0);


inline void Pause() noexcept
if(!mbIsPause)
mtPause = cppTimer::now();
mbIsPause = true;




inline void Start() noexcept
if(mbIsPause)
mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);
mbIsPause = false;





std::vector< int64_t > SessionTime()

auto now = cppTimer::now();
auto delay = std::chrono::duration_cast<std::chrono::seconds>(now - mtpNow);

if(mbIsPause)
mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);


auto tp = std::chrono::duration_cast<std::chrono::seconds>(delay - mtRestart); //+ mtRestart ;// SecondsTp(cppTimer::now()) - SecondsTp(mtpNow) + SecondsTp(mtRestart);

mvSession[sec] = tp.count()%60;
mvSession[min] = std::chrono::duration_cast<std::chrono::minutes>(tp).count()%60;
mvSession[hrs] = std::chrono::duration_cast<std::chrono::hours>(tp).count();

return mvSession;


;









share|improve this question









New contributor



Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$




















    2












    $begingroup$


    I am making a very simple stopwatch functionality as below.



    New will start the timer.

    Pause will suspend the watch.

    Start will restart again.

    Session will return the duration.



    #include<chrono>
    #include<vector>

    class Timer
    using cppTimer = std::chrono::high_resolution_clock;
    using seconds = std::chrono::seconds;
    std::vector< int64_t > mvSession;
    cppTimer::time_point mtpNow;
    cppTimer::time_point mtPause;
    seconds mtRestart;
    bool mbIsPause;
    public:

    enum Units
    sec,
    min,
    hrs,
    end
    ;

    Timer() noexcept: mbIsPause(false), mtRestart ,mvSession(3)


    inline void Now() noexcept
    mtpNow = cppTimer::now();
    mbIsPause = false;
    mtRestart = seconds(0);


    inline void Pause() noexcept
    if(!mbIsPause)
    mtPause = cppTimer::now();
    mbIsPause = true;




    inline void Start() noexcept
    if(mbIsPause)
    mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);
    mbIsPause = false;





    std::vector< int64_t > SessionTime()

    auto now = cppTimer::now();
    auto delay = std::chrono::duration_cast<std::chrono::seconds>(now - mtpNow);

    if(mbIsPause)
    mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);


    auto tp = std::chrono::duration_cast<std::chrono::seconds>(delay - mtRestart); //+ mtRestart ;// SecondsTp(cppTimer::now()) - SecondsTp(mtpNow) + SecondsTp(mtRestart);

    mvSession[sec] = tp.count()%60;
    mvSession[min] = std::chrono::duration_cast<std::chrono::minutes>(tp).count()%60;
    mvSession[hrs] = std::chrono::duration_cast<std::chrono::hours>(tp).count();

    return mvSession;


    ;









    share|improve this question









    New contributor



    Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    $endgroup$
















      2












      2








      2


      1



      $begingroup$


      I am making a very simple stopwatch functionality as below.



      New will start the timer.

      Pause will suspend the watch.

      Start will restart again.

      Session will return the duration.



      #include<chrono>
      #include<vector>

      class Timer
      using cppTimer = std::chrono::high_resolution_clock;
      using seconds = std::chrono::seconds;
      std::vector< int64_t > mvSession;
      cppTimer::time_point mtpNow;
      cppTimer::time_point mtPause;
      seconds mtRestart;
      bool mbIsPause;
      public:

      enum Units
      sec,
      min,
      hrs,
      end
      ;

      Timer() noexcept: mbIsPause(false), mtRestart ,mvSession(3)


      inline void Now() noexcept
      mtpNow = cppTimer::now();
      mbIsPause = false;
      mtRestart = seconds(0);


      inline void Pause() noexcept
      if(!mbIsPause)
      mtPause = cppTimer::now();
      mbIsPause = true;




      inline void Start() noexcept
      if(mbIsPause)
      mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);
      mbIsPause = false;





      std::vector< int64_t > SessionTime()

      auto now = cppTimer::now();
      auto delay = std::chrono::duration_cast<std::chrono::seconds>(now - mtpNow);

      if(mbIsPause)
      mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);


      auto tp = std::chrono::duration_cast<std::chrono::seconds>(delay - mtRestart); //+ mtRestart ;// SecondsTp(cppTimer::now()) - SecondsTp(mtpNow) + SecondsTp(mtRestart);

      mvSession[sec] = tp.count()%60;
      mvSession[min] = std::chrono::duration_cast<std::chrono::minutes>(tp).count()%60;
      mvSession[hrs] = std::chrono::duration_cast<std::chrono::hours>(tp).count();

      return mvSession;


      ;









      share|improve this question









      New contributor



      Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      $endgroup$




      I am making a very simple stopwatch functionality as below.



      New will start the timer.

      Pause will suspend the watch.

      Start will restart again.

      Session will return the duration.



      #include<chrono>
      #include<vector>

      class Timer
      using cppTimer = std::chrono::high_resolution_clock;
      using seconds = std::chrono::seconds;
      std::vector< int64_t > mvSession;
      cppTimer::time_point mtpNow;
      cppTimer::time_point mtPause;
      seconds mtRestart;
      bool mbIsPause;
      public:

      enum Units
      sec,
      min,
      hrs,
      end
      ;

      Timer() noexcept: mbIsPause(false), mtRestart ,mvSession(3)


      inline void Now() noexcept
      mtpNow = cppTimer::now();
      mbIsPause = false;
      mtRestart = seconds(0);


      inline void Pause() noexcept
      if(!mbIsPause)
      mtPause = cppTimer::now();
      mbIsPause = true;




      inline void Start() noexcept
      if(mbIsPause)
      mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);
      mbIsPause = false;





      std::vector< int64_t > SessionTime()

      auto now = cppTimer::now();
      auto delay = std::chrono::duration_cast<std::chrono::seconds>(now - mtpNow);

      if(mbIsPause)
      mtRestart += std::chrono::duration_cast<std::chrono::seconds>(cppTimer::now() - mtPause);


      auto tp = std::chrono::duration_cast<std::chrono::seconds>(delay - mtRestart); //+ mtRestart ;// SecondsTp(cppTimer::now()) - SecondsTp(mtpNow) + SecondsTp(mtRestart);

      mvSession[sec] = tp.count()%60;
      mvSession[min] = std::chrono::duration_cast<std::chrono::minutes>(tp).count()%60;
      mvSession[hrs] = std::chrono::duration_cast<std::chrono::hours>(tp).count();

      return mvSession;


      ;






      c++ timer






      share|improve this question









      New contributor



      Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share|improve this question









      New contributor



      Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share|improve this question




      share|improve this question








      edited 2 hours ago









      Peter Mortensen

      2621 silver badge7 bronze badges




      2621 silver badge7 bronze badges






      New contributor



      Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      asked 20 hours ago









      MohitMohit

      111 bronze badge




      111 bronze badge




      New contributor



      Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




      New contributor




      Mohit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.

























          2 Answers
          2






          active

          oldest

          votes


















          6












          $begingroup$

          Don't use member variables for temporary storage



          Your class Timer has a member variable mvSession, which is unnecessary. It is only used in SessionTime(), where it is filled in and returned. No other functions use it. Instead, just declare std::vector<int64_t> mvSession(3) inside SessionTime().



          By making it a member variable, you introduced two problems: first, your class now uses more memory than necessary. Second, the function SessionTime() is now no longer reentrant; if two threads would call SessionTime() simultaneously, they would both write to the same mvSession variable, potentially corrupting it.



          Use std::chrono::steady_clock for timers



          The problem with std::chrono::high_resolution_clock() is that it is not guaranteed what kind of clock it is. It can represent wall clock time, which can jump ahead or forwards because of summer and winter time, leap seconds, the computer suspending and resuming. This is not something you want for a timer where you are interested in a simple duration. For this, you want to use std::chrono::steady_clock, which is guaranteed to be a monotonically increasing clock. Also, your function SessionTime() returns the time in a resolution of seconds, so you don't need a high resolution clock anyway.



          Don't use Hungarian notation



          There might be some merits to Hungarian notation, but it really isn't necessary to use it for C++, since the compiler will do type checking for you. Moreover, it's easy to use the wrong prefix, and it's hard to come up with a reasonable prefix when you can have complex types.



          You are already making mistakes in your code. For example, mtpNow and mtPause are both of type cppTimer::time_point. So the prefix should have been the same. And mtRestart has a different type than mtPause, so their prefixes should have been different. I recommend that you just avoid using Hungarian notation altoghether.



          Be consistent with using



          You are declaring using seconds = std::chrono::seconds, and use seconds in a few places, but you also use std::chrono::seconds in a lot of places. Furthermore, you also use std::chrono::minutes and std::chrono::hours, but have not declared an alias for them. In this case, I suggest you don't declare using seconds at all.



          I would keep using cppTimer though, since it basically selects which clock to use. That makes it easier to change the clock later by just changing one line of code. I would write using clock = ... though, to be consistent with the C++ library itself.



          Don't cast to seconds too early



          Instead of seconds mtRestart, use cppTimer::duration mtRestart. This will keep the accuracy of the duration to the same as the clock itself. Only cast durations to seconds or other time intervals until the last moment possible. The same goes for the calculation of delay in SessionTime(), just write:



          auto delay = now - mtpNow;


          Use nouns for variable names, verbs for function names



          A variable holds (the value of) a thing, so its name should naturally be a noun. Functions do stuff, so there names should generally be verbs. The function Now() should actually be named Start(). Your function Start() should probably be named Continue(). The function SessionTime() calculates how long the timer has been running for, so probably should be named GetDuration().



          Conversely, the variables mtPause and mtRestart should be renamed to nouns as well. They are a bit confusing. Sure, you set mtPause in the Pause() function, but it doesn't describe what the value actually means. The same goes for mtRestart. I would instead write:



          clock::time_point StartTime;
          clock::time_point PauseTime;
          clock::duration PausedDuration;
          bool IsPaused;


          Now you can rewrite the function Now() to:



          void Start() 
          StartTime = clock::now();
          IsPaused = false;
          PausedDuration = ;



          Remove mtRestart



          You are using two variables to handle the timer being paused, mtPause and mtRestart. However, you only need one. In the Pause() function, you indeed just record when this function is called. However, when restarting the timer, instead of adding the duration of being paused to mtRestart, just add that duration to mtpNow instead:



          void Start() 
          if(mbIsPause)
          mtpNow += cppTimer::now() - mtPause;
          mbIsPause = false;




          This also simplifies SessionTime():



          std::vector<int64_t> SessionTime() 
          auto end = mbIsPause ? mtPause : cppTimer::now();
          auto tp = std::chrono::duration_cast<std::chrono::seconds>(end - mtpNow);
          ...



          Also, since mtPause is only ever 0 when you didn't pause, you can use that to signal whether the timer is paused instead of having bool mbIsPause.



          Another option is @user673679's suggestion of storing only the start time and the accumulated elapsed time so far. You would then use the start time being equal to as a signal that the timer has not been started.



          Just return a std::chrono::duration



          When you want the elapsed time, I would avoid having the Timer class be responsible for converting the duration to a vector of integers representing hours, minutes and seconds. It reduces the accuracy of your timer. Instead, I would just return a std::chrono::duration, and have the caller decide whether it wants to convert that to something. It also is much more efficient than having to construct a std::vector<int64_t>.



          Try to make it behave reasonable in all situations



          One issue with your code is that it only gives reasonable results for SessionTime() if you have called Now() at least once. You didn't initialize mtpNow, and even if it was value-initialized to zero, then SessionTime() will return the time that has passed since the epoch.



          If you want the Timer to behave like it was started at construction time, then initialize mtpNow to cppTimer::now(). If you want it to behave like it was paused, then ensure both mtpNow and mtPause are initialized to the same value (I suggest just using ), and that mbIsPause is true.



          Make it work like a real stopwatch



          As already suggested by others, it helps to think of a timer as a stopwatch. A real stopwatch starts in a stopped state, showing an elapsed time of zero. Then, you can start and stop the timer mechanism with buttons. Usually, there is a separate button to reset the stopwatch to its initial state. By making the class act like something a lot of people are already familiar with, the code is easier to understand for others.



          Reworked code



          Here is an example of what the code would look like with my suggestions applied, as well as @user673679's way of storing the elapsed time between previous start and stops of the clock:



          #include <chrono>

          class Timer
          using clock = std::chrono::steady_clock;
          clock::time_point StartTime = ;
          clock::duration ElapsedTime = ;

          public:
          bool IsRunning() const
          return StartTime != clock::time_point;


          void Start()
          if(!IsRunning())
          StartTime = clock::now();



          void Stop()
          if(IsRunning())
          ElapsedTime += clock::now() - StartTime;
          StartTime = ;



          void Reset()
          StartTime = ;
          ElapsedTime = ;


          clock::duration GetElapsed()
          auto result = ElapsedTime;
          if(IsRunning())
          result += clock::now() - StartTime;

          return result;

          ;
          ```





          share|improve this answer











          $endgroup$














          • $begingroup$
            That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
            $endgroup$
            – Peter Mortensen
            5 hours ago



















          2












          $begingroup$

          • It's fine to prefix member variables with an m, but it's probably best to avoid type prefixes (e.g. mtpNow). It makes code harder to read (you have to know what every abbreviation means), it's a pain to maintain (e.g. mtPause should probably be mtpPause to be consistent). Modern tools eliminate the need for this too (mousing over a variable in Visual Studio will tell me the exact type, not an approximation).


          • Functions defined inline in the class don't need to be declared inline.



          • The naming is very confusing:



            • Now() differs from the standard library (now() returns the current time, and is arguably still a terrible name). Functions names should be commands or questions. Perhaps Restart() or Reset() would be better.


            • Start() is also not ideal. One might expect the function to do what Now() does. I'd suggest calling it Unpause(), which makes the purpose clearer.


            • mtRestart is an odd name for the time spent paused.



          • We don't really need the Now() / Restart() function, since we can just assign a new timer to the old one to do the same thing (e.g. Timer timer; ...; timer = Timer(); // restarted!).


          • There's no reason to keep a vector in the class (we're copying it every time anyway, so we might as well just create a new vector each time).


          • We don't need a vector, since it always has 3 values, it would be neater to return a simple struct, which would allow us to give each value a name. Or...


          • The real solution is to just return an appropriate chrono:: type, and let the user worry about formatting / converting it.


          • I'd suggest naming the class Stopwatch, since that's more specific to the pausable timing functionality we need. We can actually implement this functionality based on a simpler, non-pausable Timer class.



          So overall I'd suggest something more like this (not tested properly):



          #include <chrono>

          template<class ClockT = std::chrono::high_resolution_clock>
          class Timer

          ClockT::time_point m_start;

          public:

          Timer():
          m_start(ClockT::now())




          ClockT::duration GetElapsedTime() const

          return ClockT::now() - m_start;

          ;

          template<class ClockT = std::chrono::high_resolution_clock>
          class Stopwatch

          bool m_paused;
          Timer<ClockT> m_timer;
          ClockT::duration m_timeAccumulated;

          public:

          explicit Stopwatch(bool paused = false):
          m_paused(paused),
          m_timer(),
          m_timeAccumulated(0)




          void Pause()

          m_timeAccumulated += m_timer.GetElapsedTime();
          m_paused = true;


          void Unpause()

          if (m_paused)

          m_timer = Timer<ClockT>();
          m_paused = false;



          ClockT::duration GetElapsedTime() const

          if (m_paused)
          return m_timeAccumulated;

          return m_timeAccumulated + m_timer.GetElapsedTime();

          ;

          #include <iostream>

          int main()

          using seconds_t = std::chrono::duration<float>;

          Stopwatch s;

          for (int i = 0; i != 50; ++i) std::cout << ".";
          std::cout << "n";

          std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

          s = Stopwatch(true);
          std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

          s.Unpause();

          for (int i = 0; i != 50; ++i) std::cout << ".";
          std::cout << "n";

          s.Pause();
          std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

          for (int i = 0; i != 50; ++i) std::cout << ".";
          std::cout << "n";

          std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;






          share|improve this answer









          $endgroup$

















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );






            Mohit is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225923%2fa-simple-stop-watch-which-i-want-to-extend%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            6












            $begingroup$

            Don't use member variables for temporary storage



            Your class Timer has a member variable mvSession, which is unnecessary. It is only used in SessionTime(), where it is filled in and returned. No other functions use it. Instead, just declare std::vector<int64_t> mvSession(3) inside SessionTime().



            By making it a member variable, you introduced two problems: first, your class now uses more memory than necessary. Second, the function SessionTime() is now no longer reentrant; if two threads would call SessionTime() simultaneously, they would both write to the same mvSession variable, potentially corrupting it.



            Use std::chrono::steady_clock for timers



            The problem with std::chrono::high_resolution_clock() is that it is not guaranteed what kind of clock it is. It can represent wall clock time, which can jump ahead or forwards because of summer and winter time, leap seconds, the computer suspending and resuming. This is not something you want for a timer where you are interested in a simple duration. For this, you want to use std::chrono::steady_clock, which is guaranteed to be a monotonically increasing clock. Also, your function SessionTime() returns the time in a resolution of seconds, so you don't need a high resolution clock anyway.



            Don't use Hungarian notation



            There might be some merits to Hungarian notation, but it really isn't necessary to use it for C++, since the compiler will do type checking for you. Moreover, it's easy to use the wrong prefix, and it's hard to come up with a reasonable prefix when you can have complex types.



            You are already making mistakes in your code. For example, mtpNow and mtPause are both of type cppTimer::time_point. So the prefix should have been the same. And mtRestart has a different type than mtPause, so their prefixes should have been different. I recommend that you just avoid using Hungarian notation altoghether.



            Be consistent with using



            You are declaring using seconds = std::chrono::seconds, and use seconds in a few places, but you also use std::chrono::seconds in a lot of places. Furthermore, you also use std::chrono::minutes and std::chrono::hours, but have not declared an alias for them. In this case, I suggest you don't declare using seconds at all.



            I would keep using cppTimer though, since it basically selects which clock to use. That makes it easier to change the clock later by just changing one line of code. I would write using clock = ... though, to be consistent with the C++ library itself.



            Don't cast to seconds too early



            Instead of seconds mtRestart, use cppTimer::duration mtRestart. This will keep the accuracy of the duration to the same as the clock itself. Only cast durations to seconds or other time intervals until the last moment possible. The same goes for the calculation of delay in SessionTime(), just write:



            auto delay = now - mtpNow;


            Use nouns for variable names, verbs for function names



            A variable holds (the value of) a thing, so its name should naturally be a noun. Functions do stuff, so there names should generally be verbs. The function Now() should actually be named Start(). Your function Start() should probably be named Continue(). The function SessionTime() calculates how long the timer has been running for, so probably should be named GetDuration().



            Conversely, the variables mtPause and mtRestart should be renamed to nouns as well. They are a bit confusing. Sure, you set mtPause in the Pause() function, but it doesn't describe what the value actually means. The same goes for mtRestart. I would instead write:



            clock::time_point StartTime;
            clock::time_point PauseTime;
            clock::duration PausedDuration;
            bool IsPaused;


            Now you can rewrite the function Now() to:



            void Start() 
            StartTime = clock::now();
            IsPaused = false;
            PausedDuration = ;



            Remove mtRestart



            You are using two variables to handle the timer being paused, mtPause and mtRestart. However, you only need one. In the Pause() function, you indeed just record when this function is called. However, when restarting the timer, instead of adding the duration of being paused to mtRestart, just add that duration to mtpNow instead:



            void Start() 
            if(mbIsPause)
            mtpNow += cppTimer::now() - mtPause;
            mbIsPause = false;




            This also simplifies SessionTime():



            std::vector<int64_t> SessionTime() 
            auto end = mbIsPause ? mtPause : cppTimer::now();
            auto tp = std::chrono::duration_cast<std::chrono::seconds>(end - mtpNow);
            ...



            Also, since mtPause is only ever 0 when you didn't pause, you can use that to signal whether the timer is paused instead of having bool mbIsPause.



            Another option is @user673679's suggestion of storing only the start time and the accumulated elapsed time so far. You would then use the start time being equal to as a signal that the timer has not been started.



            Just return a std::chrono::duration



            When you want the elapsed time, I would avoid having the Timer class be responsible for converting the duration to a vector of integers representing hours, minutes and seconds. It reduces the accuracy of your timer. Instead, I would just return a std::chrono::duration, and have the caller decide whether it wants to convert that to something. It also is much more efficient than having to construct a std::vector<int64_t>.



            Try to make it behave reasonable in all situations



            One issue with your code is that it only gives reasonable results for SessionTime() if you have called Now() at least once. You didn't initialize mtpNow, and even if it was value-initialized to zero, then SessionTime() will return the time that has passed since the epoch.



            If you want the Timer to behave like it was started at construction time, then initialize mtpNow to cppTimer::now(). If you want it to behave like it was paused, then ensure both mtpNow and mtPause are initialized to the same value (I suggest just using ), and that mbIsPause is true.



            Make it work like a real stopwatch



            As already suggested by others, it helps to think of a timer as a stopwatch. A real stopwatch starts in a stopped state, showing an elapsed time of zero. Then, you can start and stop the timer mechanism with buttons. Usually, there is a separate button to reset the stopwatch to its initial state. By making the class act like something a lot of people are already familiar with, the code is easier to understand for others.



            Reworked code



            Here is an example of what the code would look like with my suggestions applied, as well as @user673679's way of storing the elapsed time between previous start and stops of the clock:



            #include <chrono>

            class Timer
            using clock = std::chrono::steady_clock;
            clock::time_point StartTime = ;
            clock::duration ElapsedTime = ;

            public:
            bool IsRunning() const
            return StartTime != clock::time_point;


            void Start()
            if(!IsRunning())
            StartTime = clock::now();



            void Stop()
            if(IsRunning())
            ElapsedTime += clock::now() - StartTime;
            StartTime = ;



            void Reset()
            StartTime = ;
            ElapsedTime = ;


            clock::duration GetElapsed()
            auto result = ElapsedTime;
            if(IsRunning())
            result += clock::now() - StartTime;

            return result;

            ;
            ```





            share|improve this answer











            $endgroup$














            • $begingroup$
              That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
              $endgroup$
              – Peter Mortensen
              5 hours ago
















            6












            $begingroup$

            Don't use member variables for temporary storage



            Your class Timer has a member variable mvSession, which is unnecessary. It is only used in SessionTime(), where it is filled in and returned. No other functions use it. Instead, just declare std::vector<int64_t> mvSession(3) inside SessionTime().



            By making it a member variable, you introduced two problems: first, your class now uses more memory than necessary. Second, the function SessionTime() is now no longer reentrant; if two threads would call SessionTime() simultaneously, they would both write to the same mvSession variable, potentially corrupting it.



            Use std::chrono::steady_clock for timers



            The problem with std::chrono::high_resolution_clock() is that it is not guaranteed what kind of clock it is. It can represent wall clock time, which can jump ahead or forwards because of summer and winter time, leap seconds, the computer suspending and resuming. This is not something you want for a timer where you are interested in a simple duration. For this, you want to use std::chrono::steady_clock, which is guaranteed to be a monotonically increasing clock. Also, your function SessionTime() returns the time in a resolution of seconds, so you don't need a high resolution clock anyway.



            Don't use Hungarian notation



            There might be some merits to Hungarian notation, but it really isn't necessary to use it for C++, since the compiler will do type checking for you. Moreover, it's easy to use the wrong prefix, and it's hard to come up with a reasonable prefix when you can have complex types.



            You are already making mistakes in your code. For example, mtpNow and mtPause are both of type cppTimer::time_point. So the prefix should have been the same. And mtRestart has a different type than mtPause, so their prefixes should have been different. I recommend that you just avoid using Hungarian notation altoghether.



            Be consistent with using



            You are declaring using seconds = std::chrono::seconds, and use seconds in a few places, but you also use std::chrono::seconds in a lot of places. Furthermore, you also use std::chrono::minutes and std::chrono::hours, but have not declared an alias for them. In this case, I suggest you don't declare using seconds at all.



            I would keep using cppTimer though, since it basically selects which clock to use. That makes it easier to change the clock later by just changing one line of code. I would write using clock = ... though, to be consistent with the C++ library itself.



            Don't cast to seconds too early



            Instead of seconds mtRestart, use cppTimer::duration mtRestart. This will keep the accuracy of the duration to the same as the clock itself. Only cast durations to seconds or other time intervals until the last moment possible. The same goes for the calculation of delay in SessionTime(), just write:



            auto delay = now - mtpNow;


            Use nouns for variable names, verbs for function names



            A variable holds (the value of) a thing, so its name should naturally be a noun. Functions do stuff, so there names should generally be verbs. The function Now() should actually be named Start(). Your function Start() should probably be named Continue(). The function SessionTime() calculates how long the timer has been running for, so probably should be named GetDuration().



            Conversely, the variables mtPause and mtRestart should be renamed to nouns as well. They are a bit confusing. Sure, you set mtPause in the Pause() function, but it doesn't describe what the value actually means. The same goes for mtRestart. I would instead write:



            clock::time_point StartTime;
            clock::time_point PauseTime;
            clock::duration PausedDuration;
            bool IsPaused;


            Now you can rewrite the function Now() to:



            void Start() 
            StartTime = clock::now();
            IsPaused = false;
            PausedDuration = ;



            Remove mtRestart



            You are using two variables to handle the timer being paused, mtPause and mtRestart. However, you only need one. In the Pause() function, you indeed just record when this function is called. However, when restarting the timer, instead of adding the duration of being paused to mtRestart, just add that duration to mtpNow instead:



            void Start() 
            if(mbIsPause)
            mtpNow += cppTimer::now() - mtPause;
            mbIsPause = false;




            This also simplifies SessionTime():



            std::vector<int64_t> SessionTime() 
            auto end = mbIsPause ? mtPause : cppTimer::now();
            auto tp = std::chrono::duration_cast<std::chrono::seconds>(end - mtpNow);
            ...



            Also, since mtPause is only ever 0 when you didn't pause, you can use that to signal whether the timer is paused instead of having bool mbIsPause.



            Another option is @user673679's suggestion of storing only the start time and the accumulated elapsed time so far. You would then use the start time being equal to as a signal that the timer has not been started.



            Just return a std::chrono::duration



            When you want the elapsed time, I would avoid having the Timer class be responsible for converting the duration to a vector of integers representing hours, minutes and seconds. It reduces the accuracy of your timer. Instead, I would just return a std::chrono::duration, and have the caller decide whether it wants to convert that to something. It also is much more efficient than having to construct a std::vector<int64_t>.



            Try to make it behave reasonable in all situations



            One issue with your code is that it only gives reasonable results for SessionTime() if you have called Now() at least once. You didn't initialize mtpNow, and even if it was value-initialized to zero, then SessionTime() will return the time that has passed since the epoch.



            If you want the Timer to behave like it was started at construction time, then initialize mtpNow to cppTimer::now(). If you want it to behave like it was paused, then ensure both mtpNow and mtPause are initialized to the same value (I suggest just using ), and that mbIsPause is true.



            Make it work like a real stopwatch



            As already suggested by others, it helps to think of a timer as a stopwatch. A real stopwatch starts in a stopped state, showing an elapsed time of zero. Then, you can start and stop the timer mechanism with buttons. Usually, there is a separate button to reset the stopwatch to its initial state. By making the class act like something a lot of people are already familiar with, the code is easier to understand for others.



            Reworked code



            Here is an example of what the code would look like with my suggestions applied, as well as @user673679's way of storing the elapsed time between previous start and stops of the clock:



            #include <chrono>

            class Timer
            using clock = std::chrono::steady_clock;
            clock::time_point StartTime = ;
            clock::duration ElapsedTime = ;

            public:
            bool IsRunning() const
            return StartTime != clock::time_point;


            void Start()
            if(!IsRunning())
            StartTime = clock::now();



            void Stop()
            if(IsRunning())
            ElapsedTime += clock::now() - StartTime;
            StartTime = ;



            void Reset()
            StartTime = ;
            ElapsedTime = ;


            clock::duration GetElapsed()
            auto result = ElapsedTime;
            if(IsRunning())
            result += clock::now() - StartTime;

            return result;

            ;
            ```





            share|improve this answer











            $endgroup$














            • $begingroup$
              That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
              $endgroup$
              – Peter Mortensen
              5 hours ago














            6












            6








            6





            $begingroup$

            Don't use member variables for temporary storage



            Your class Timer has a member variable mvSession, which is unnecessary. It is only used in SessionTime(), where it is filled in and returned. No other functions use it. Instead, just declare std::vector<int64_t> mvSession(3) inside SessionTime().



            By making it a member variable, you introduced two problems: first, your class now uses more memory than necessary. Second, the function SessionTime() is now no longer reentrant; if two threads would call SessionTime() simultaneously, they would both write to the same mvSession variable, potentially corrupting it.



            Use std::chrono::steady_clock for timers



            The problem with std::chrono::high_resolution_clock() is that it is not guaranteed what kind of clock it is. It can represent wall clock time, which can jump ahead or forwards because of summer and winter time, leap seconds, the computer suspending and resuming. This is not something you want for a timer where you are interested in a simple duration. For this, you want to use std::chrono::steady_clock, which is guaranteed to be a monotonically increasing clock. Also, your function SessionTime() returns the time in a resolution of seconds, so you don't need a high resolution clock anyway.



            Don't use Hungarian notation



            There might be some merits to Hungarian notation, but it really isn't necessary to use it for C++, since the compiler will do type checking for you. Moreover, it's easy to use the wrong prefix, and it's hard to come up with a reasonable prefix when you can have complex types.



            You are already making mistakes in your code. For example, mtpNow and mtPause are both of type cppTimer::time_point. So the prefix should have been the same. And mtRestart has a different type than mtPause, so their prefixes should have been different. I recommend that you just avoid using Hungarian notation altoghether.



            Be consistent with using



            You are declaring using seconds = std::chrono::seconds, and use seconds in a few places, but you also use std::chrono::seconds in a lot of places. Furthermore, you also use std::chrono::minutes and std::chrono::hours, but have not declared an alias for them. In this case, I suggest you don't declare using seconds at all.



            I would keep using cppTimer though, since it basically selects which clock to use. That makes it easier to change the clock later by just changing one line of code. I would write using clock = ... though, to be consistent with the C++ library itself.



            Don't cast to seconds too early



            Instead of seconds mtRestart, use cppTimer::duration mtRestart. This will keep the accuracy of the duration to the same as the clock itself. Only cast durations to seconds or other time intervals until the last moment possible. The same goes for the calculation of delay in SessionTime(), just write:



            auto delay = now - mtpNow;


            Use nouns for variable names, verbs for function names



            A variable holds (the value of) a thing, so its name should naturally be a noun. Functions do stuff, so there names should generally be verbs. The function Now() should actually be named Start(). Your function Start() should probably be named Continue(). The function SessionTime() calculates how long the timer has been running for, so probably should be named GetDuration().



            Conversely, the variables mtPause and mtRestart should be renamed to nouns as well. They are a bit confusing. Sure, you set mtPause in the Pause() function, but it doesn't describe what the value actually means. The same goes for mtRestart. I would instead write:



            clock::time_point StartTime;
            clock::time_point PauseTime;
            clock::duration PausedDuration;
            bool IsPaused;


            Now you can rewrite the function Now() to:



            void Start() 
            StartTime = clock::now();
            IsPaused = false;
            PausedDuration = ;



            Remove mtRestart



            You are using two variables to handle the timer being paused, mtPause and mtRestart. However, you only need one. In the Pause() function, you indeed just record when this function is called. However, when restarting the timer, instead of adding the duration of being paused to mtRestart, just add that duration to mtpNow instead:



            void Start() 
            if(mbIsPause)
            mtpNow += cppTimer::now() - mtPause;
            mbIsPause = false;




            This also simplifies SessionTime():



            std::vector<int64_t> SessionTime() 
            auto end = mbIsPause ? mtPause : cppTimer::now();
            auto tp = std::chrono::duration_cast<std::chrono::seconds>(end - mtpNow);
            ...



            Also, since mtPause is only ever 0 when you didn't pause, you can use that to signal whether the timer is paused instead of having bool mbIsPause.



            Another option is @user673679's suggestion of storing only the start time and the accumulated elapsed time so far. You would then use the start time being equal to as a signal that the timer has not been started.



            Just return a std::chrono::duration



            When you want the elapsed time, I would avoid having the Timer class be responsible for converting the duration to a vector of integers representing hours, minutes and seconds. It reduces the accuracy of your timer. Instead, I would just return a std::chrono::duration, and have the caller decide whether it wants to convert that to something. It also is much more efficient than having to construct a std::vector<int64_t>.



            Try to make it behave reasonable in all situations



            One issue with your code is that it only gives reasonable results for SessionTime() if you have called Now() at least once. You didn't initialize mtpNow, and even if it was value-initialized to zero, then SessionTime() will return the time that has passed since the epoch.



            If you want the Timer to behave like it was started at construction time, then initialize mtpNow to cppTimer::now(). If you want it to behave like it was paused, then ensure both mtpNow and mtPause are initialized to the same value (I suggest just using ), and that mbIsPause is true.



            Make it work like a real stopwatch



            As already suggested by others, it helps to think of a timer as a stopwatch. A real stopwatch starts in a stopped state, showing an elapsed time of zero. Then, you can start and stop the timer mechanism with buttons. Usually, there is a separate button to reset the stopwatch to its initial state. By making the class act like something a lot of people are already familiar with, the code is easier to understand for others.



            Reworked code



            Here is an example of what the code would look like with my suggestions applied, as well as @user673679's way of storing the elapsed time between previous start and stops of the clock:



            #include <chrono>

            class Timer
            using clock = std::chrono::steady_clock;
            clock::time_point StartTime = ;
            clock::duration ElapsedTime = ;

            public:
            bool IsRunning() const
            return StartTime != clock::time_point;


            void Start()
            if(!IsRunning())
            StartTime = clock::now();



            void Stop()
            if(IsRunning())
            ElapsedTime += clock::now() - StartTime;
            StartTime = ;



            void Reset()
            StartTime = ;
            ElapsedTime = ;


            clock::duration GetElapsed()
            auto result = ElapsedTime;
            if(IsRunning())
            result += clock::now() - StartTime;

            return result;

            ;
            ```





            share|improve this answer











            $endgroup$



            Don't use member variables for temporary storage



            Your class Timer has a member variable mvSession, which is unnecessary. It is only used in SessionTime(), where it is filled in and returned. No other functions use it. Instead, just declare std::vector<int64_t> mvSession(3) inside SessionTime().



            By making it a member variable, you introduced two problems: first, your class now uses more memory than necessary. Second, the function SessionTime() is now no longer reentrant; if two threads would call SessionTime() simultaneously, they would both write to the same mvSession variable, potentially corrupting it.



            Use std::chrono::steady_clock for timers



            The problem with std::chrono::high_resolution_clock() is that it is not guaranteed what kind of clock it is. It can represent wall clock time, which can jump ahead or forwards because of summer and winter time, leap seconds, the computer suspending and resuming. This is not something you want for a timer where you are interested in a simple duration. For this, you want to use std::chrono::steady_clock, which is guaranteed to be a monotonically increasing clock. Also, your function SessionTime() returns the time in a resolution of seconds, so you don't need a high resolution clock anyway.



            Don't use Hungarian notation



            There might be some merits to Hungarian notation, but it really isn't necessary to use it for C++, since the compiler will do type checking for you. Moreover, it's easy to use the wrong prefix, and it's hard to come up with a reasonable prefix when you can have complex types.



            You are already making mistakes in your code. For example, mtpNow and mtPause are both of type cppTimer::time_point. So the prefix should have been the same. And mtRestart has a different type than mtPause, so their prefixes should have been different. I recommend that you just avoid using Hungarian notation altoghether.



            Be consistent with using



            You are declaring using seconds = std::chrono::seconds, and use seconds in a few places, but you also use std::chrono::seconds in a lot of places. Furthermore, you also use std::chrono::minutes and std::chrono::hours, but have not declared an alias for them. In this case, I suggest you don't declare using seconds at all.



            I would keep using cppTimer though, since it basically selects which clock to use. That makes it easier to change the clock later by just changing one line of code. I would write using clock = ... though, to be consistent with the C++ library itself.



            Don't cast to seconds too early



            Instead of seconds mtRestart, use cppTimer::duration mtRestart. This will keep the accuracy of the duration to the same as the clock itself. Only cast durations to seconds or other time intervals until the last moment possible. The same goes for the calculation of delay in SessionTime(), just write:



            auto delay = now - mtpNow;


            Use nouns for variable names, verbs for function names



            A variable holds (the value of) a thing, so its name should naturally be a noun. Functions do stuff, so there names should generally be verbs. The function Now() should actually be named Start(). Your function Start() should probably be named Continue(). The function SessionTime() calculates how long the timer has been running for, so probably should be named GetDuration().



            Conversely, the variables mtPause and mtRestart should be renamed to nouns as well. They are a bit confusing. Sure, you set mtPause in the Pause() function, but it doesn't describe what the value actually means. The same goes for mtRestart. I would instead write:



            clock::time_point StartTime;
            clock::time_point PauseTime;
            clock::duration PausedDuration;
            bool IsPaused;


            Now you can rewrite the function Now() to:



            void Start() 
            StartTime = clock::now();
            IsPaused = false;
            PausedDuration = ;



            Remove mtRestart



            You are using two variables to handle the timer being paused, mtPause and mtRestart. However, you only need one. In the Pause() function, you indeed just record when this function is called. However, when restarting the timer, instead of adding the duration of being paused to mtRestart, just add that duration to mtpNow instead:



            void Start() 
            if(mbIsPause)
            mtpNow += cppTimer::now() - mtPause;
            mbIsPause = false;




            This also simplifies SessionTime():



            std::vector<int64_t> SessionTime() 
            auto end = mbIsPause ? mtPause : cppTimer::now();
            auto tp = std::chrono::duration_cast<std::chrono::seconds>(end - mtpNow);
            ...



            Also, since mtPause is only ever 0 when you didn't pause, you can use that to signal whether the timer is paused instead of having bool mbIsPause.



            Another option is @user673679's suggestion of storing only the start time and the accumulated elapsed time so far. You would then use the start time being equal to as a signal that the timer has not been started.



            Just return a std::chrono::duration



            When you want the elapsed time, I would avoid having the Timer class be responsible for converting the duration to a vector of integers representing hours, minutes and seconds. It reduces the accuracy of your timer. Instead, I would just return a std::chrono::duration, and have the caller decide whether it wants to convert that to something. It also is much more efficient than having to construct a std::vector<int64_t>.



            Try to make it behave reasonable in all situations



            One issue with your code is that it only gives reasonable results for SessionTime() if you have called Now() at least once. You didn't initialize mtpNow, and even if it was value-initialized to zero, then SessionTime() will return the time that has passed since the epoch.



            If you want the Timer to behave like it was started at construction time, then initialize mtpNow to cppTimer::now(). If you want it to behave like it was paused, then ensure both mtpNow and mtPause are initialized to the same value (I suggest just using ), and that mbIsPause is true.



            Make it work like a real stopwatch



            As already suggested by others, it helps to think of a timer as a stopwatch. A real stopwatch starts in a stopped state, showing an elapsed time of zero. Then, you can start and stop the timer mechanism with buttons. Usually, there is a separate button to reset the stopwatch to its initial state. By making the class act like something a lot of people are already familiar with, the code is easier to understand for others.



            Reworked code



            Here is an example of what the code would look like with my suggestions applied, as well as @user673679's way of storing the elapsed time between previous start and stops of the clock:



            #include <chrono>

            class Timer
            using clock = std::chrono::steady_clock;
            clock::time_point StartTime = ;
            clock::duration ElapsedTime = ;

            public:
            bool IsRunning() const
            return StartTime != clock::time_point;


            void Start()
            if(!IsRunning())
            StartTime = clock::now();



            void Stop()
            if(IsRunning())
            ElapsedTime += clock::now() - StartTime;
            StartTime = ;



            void Reset()
            StartTime = ;
            ElapsedTime = ;


            clock::duration GetElapsed()
            auto result = ElapsedTime;
            if(IsRunning())
            result += clock::now() - StartTime;

            return result;

            ;
            ```






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 9 hours ago

























            answered 17 hours ago









            G. SliepenG. Sliepen

            1,5024 silver badges11 bronze badges




            1,5024 silver badges11 bronze badges














            • $begingroup$
              That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
              $endgroup$
              – Peter Mortensen
              5 hours ago

















            • $begingroup$
              That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
              $endgroup$
              – Peter Mortensen
              5 hours ago
















            $begingroup$
            That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
            $endgroup$
            – Peter Mortensen
            5 hours ago





            $begingroup$
            That is "system" Hungarian notation (the Microsoft Windows documentation team grossly misinterpreted the original Hungarian notation), not the original Hungarian notation (which is not about types). See e.g. Triangulation episode 277, 4 min 00 secs to 5 min 19 secs.
            $endgroup$
            – Peter Mortensen
            5 hours ago














            2












            $begingroup$

            • It's fine to prefix member variables with an m, but it's probably best to avoid type prefixes (e.g. mtpNow). It makes code harder to read (you have to know what every abbreviation means), it's a pain to maintain (e.g. mtPause should probably be mtpPause to be consistent). Modern tools eliminate the need for this too (mousing over a variable in Visual Studio will tell me the exact type, not an approximation).


            • Functions defined inline in the class don't need to be declared inline.



            • The naming is very confusing:



              • Now() differs from the standard library (now() returns the current time, and is arguably still a terrible name). Functions names should be commands or questions. Perhaps Restart() or Reset() would be better.


              • Start() is also not ideal. One might expect the function to do what Now() does. I'd suggest calling it Unpause(), which makes the purpose clearer.


              • mtRestart is an odd name for the time spent paused.



            • We don't really need the Now() / Restart() function, since we can just assign a new timer to the old one to do the same thing (e.g. Timer timer; ...; timer = Timer(); // restarted!).


            • There's no reason to keep a vector in the class (we're copying it every time anyway, so we might as well just create a new vector each time).


            • We don't need a vector, since it always has 3 values, it would be neater to return a simple struct, which would allow us to give each value a name. Or...


            • The real solution is to just return an appropriate chrono:: type, and let the user worry about formatting / converting it.


            • I'd suggest naming the class Stopwatch, since that's more specific to the pausable timing functionality we need. We can actually implement this functionality based on a simpler, non-pausable Timer class.



            So overall I'd suggest something more like this (not tested properly):



            #include <chrono>

            template<class ClockT = std::chrono::high_resolution_clock>
            class Timer

            ClockT::time_point m_start;

            public:

            Timer():
            m_start(ClockT::now())




            ClockT::duration GetElapsedTime() const

            return ClockT::now() - m_start;

            ;

            template<class ClockT = std::chrono::high_resolution_clock>
            class Stopwatch

            bool m_paused;
            Timer<ClockT> m_timer;
            ClockT::duration m_timeAccumulated;

            public:

            explicit Stopwatch(bool paused = false):
            m_paused(paused),
            m_timer(),
            m_timeAccumulated(0)




            void Pause()

            m_timeAccumulated += m_timer.GetElapsedTime();
            m_paused = true;


            void Unpause()

            if (m_paused)

            m_timer = Timer<ClockT>();
            m_paused = false;



            ClockT::duration GetElapsedTime() const

            if (m_paused)
            return m_timeAccumulated;

            return m_timeAccumulated + m_timer.GetElapsedTime();

            ;

            #include <iostream>

            int main()

            using seconds_t = std::chrono::duration<float>;

            Stopwatch s;

            for (int i = 0; i != 50; ++i) std::cout << ".";
            std::cout << "n";

            std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

            s = Stopwatch(true);
            std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

            s.Unpause();

            for (int i = 0; i != 50; ++i) std::cout << ".";
            std::cout << "n";

            s.Pause();
            std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

            for (int i = 0; i != 50; ++i) std::cout << ".";
            std::cout << "n";

            std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;






            share|improve this answer









            $endgroup$



















              2












              $begingroup$

              • It's fine to prefix member variables with an m, but it's probably best to avoid type prefixes (e.g. mtpNow). It makes code harder to read (you have to know what every abbreviation means), it's a pain to maintain (e.g. mtPause should probably be mtpPause to be consistent). Modern tools eliminate the need for this too (mousing over a variable in Visual Studio will tell me the exact type, not an approximation).


              • Functions defined inline in the class don't need to be declared inline.



              • The naming is very confusing:



                • Now() differs from the standard library (now() returns the current time, and is arguably still a terrible name). Functions names should be commands or questions. Perhaps Restart() or Reset() would be better.


                • Start() is also not ideal. One might expect the function to do what Now() does. I'd suggest calling it Unpause(), which makes the purpose clearer.


                • mtRestart is an odd name for the time spent paused.



              • We don't really need the Now() / Restart() function, since we can just assign a new timer to the old one to do the same thing (e.g. Timer timer; ...; timer = Timer(); // restarted!).


              • There's no reason to keep a vector in the class (we're copying it every time anyway, so we might as well just create a new vector each time).


              • We don't need a vector, since it always has 3 values, it would be neater to return a simple struct, which would allow us to give each value a name. Or...


              • The real solution is to just return an appropriate chrono:: type, and let the user worry about formatting / converting it.


              • I'd suggest naming the class Stopwatch, since that's more specific to the pausable timing functionality we need. We can actually implement this functionality based on a simpler, non-pausable Timer class.



              So overall I'd suggest something more like this (not tested properly):



              #include <chrono>

              template<class ClockT = std::chrono::high_resolution_clock>
              class Timer

              ClockT::time_point m_start;

              public:

              Timer():
              m_start(ClockT::now())




              ClockT::duration GetElapsedTime() const

              return ClockT::now() - m_start;

              ;

              template<class ClockT = std::chrono::high_resolution_clock>
              class Stopwatch

              bool m_paused;
              Timer<ClockT> m_timer;
              ClockT::duration m_timeAccumulated;

              public:

              explicit Stopwatch(bool paused = false):
              m_paused(paused),
              m_timer(),
              m_timeAccumulated(0)




              void Pause()

              m_timeAccumulated += m_timer.GetElapsedTime();
              m_paused = true;


              void Unpause()

              if (m_paused)

              m_timer = Timer<ClockT>();
              m_paused = false;



              ClockT::duration GetElapsedTime() const

              if (m_paused)
              return m_timeAccumulated;

              return m_timeAccumulated + m_timer.GetElapsedTime();

              ;

              #include <iostream>

              int main()

              using seconds_t = std::chrono::duration<float>;

              Stopwatch s;

              for (int i = 0; i != 50; ++i) std::cout << ".";
              std::cout << "n";

              std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

              s = Stopwatch(true);
              std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

              s.Unpause();

              for (int i = 0; i != 50; ++i) std::cout << ".";
              std::cout << "n";

              s.Pause();
              std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

              for (int i = 0; i != 50; ++i) std::cout << ".";
              std::cout << "n";

              std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;






              share|improve this answer









              $endgroup$

















                2












                2








                2





                $begingroup$

                • It's fine to prefix member variables with an m, but it's probably best to avoid type prefixes (e.g. mtpNow). It makes code harder to read (you have to know what every abbreviation means), it's a pain to maintain (e.g. mtPause should probably be mtpPause to be consistent). Modern tools eliminate the need for this too (mousing over a variable in Visual Studio will tell me the exact type, not an approximation).


                • Functions defined inline in the class don't need to be declared inline.



                • The naming is very confusing:



                  • Now() differs from the standard library (now() returns the current time, and is arguably still a terrible name). Functions names should be commands or questions. Perhaps Restart() or Reset() would be better.


                  • Start() is also not ideal. One might expect the function to do what Now() does. I'd suggest calling it Unpause(), which makes the purpose clearer.


                  • mtRestart is an odd name for the time spent paused.



                • We don't really need the Now() / Restart() function, since we can just assign a new timer to the old one to do the same thing (e.g. Timer timer; ...; timer = Timer(); // restarted!).


                • There's no reason to keep a vector in the class (we're copying it every time anyway, so we might as well just create a new vector each time).


                • We don't need a vector, since it always has 3 values, it would be neater to return a simple struct, which would allow us to give each value a name. Or...


                • The real solution is to just return an appropriate chrono:: type, and let the user worry about formatting / converting it.


                • I'd suggest naming the class Stopwatch, since that's more specific to the pausable timing functionality we need. We can actually implement this functionality based on a simpler, non-pausable Timer class.



                So overall I'd suggest something more like this (not tested properly):



                #include <chrono>

                template<class ClockT = std::chrono::high_resolution_clock>
                class Timer

                ClockT::time_point m_start;

                public:

                Timer():
                m_start(ClockT::now())




                ClockT::duration GetElapsedTime() const

                return ClockT::now() - m_start;

                ;

                template<class ClockT = std::chrono::high_resolution_clock>
                class Stopwatch

                bool m_paused;
                Timer<ClockT> m_timer;
                ClockT::duration m_timeAccumulated;

                public:

                explicit Stopwatch(bool paused = false):
                m_paused(paused),
                m_timer(),
                m_timeAccumulated(0)




                void Pause()

                m_timeAccumulated += m_timer.GetElapsedTime();
                m_paused = true;


                void Unpause()

                if (m_paused)

                m_timer = Timer<ClockT>();
                m_paused = false;



                ClockT::duration GetElapsedTime() const

                if (m_paused)
                return m_timeAccumulated;

                return m_timeAccumulated + m_timer.GetElapsedTime();

                ;

                #include <iostream>

                int main()

                using seconds_t = std::chrono::duration<float>;

                Stopwatch s;

                for (int i = 0; i != 50; ++i) std::cout << ".";
                std::cout << "n";

                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

                s = Stopwatch(true);
                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

                s.Unpause();

                for (int i = 0; i != 50; ++i) std::cout << ".";
                std::cout << "n";

                s.Pause();
                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

                for (int i = 0; i != 50; ++i) std::cout << ".";
                std::cout << "n";

                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;






                share|improve this answer









                $endgroup$



                • It's fine to prefix member variables with an m, but it's probably best to avoid type prefixes (e.g. mtpNow). It makes code harder to read (you have to know what every abbreviation means), it's a pain to maintain (e.g. mtPause should probably be mtpPause to be consistent). Modern tools eliminate the need for this too (mousing over a variable in Visual Studio will tell me the exact type, not an approximation).


                • Functions defined inline in the class don't need to be declared inline.



                • The naming is very confusing:



                  • Now() differs from the standard library (now() returns the current time, and is arguably still a terrible name). Functions names should be commands or questions. Perhaps Restart() or Reset() would be better.


                  • Start() is also not ideal. One might expect the function to do what Now() does. I'd suggest calling it Unpause(), which makes the purpose clearer.


                  • mtRestart is an odd name for the time spent paused.



                • We don't really need the Now() / Restart() function, since we can just assign a new timer to the old one to do the same thing (e.g. Timer timer; ...; timer = Timer(); // restarted!).


                • There's no reason to keep a vector in the class (we're copying it every time anyway, so we might as well just create a new vector each time).


                • We don't need a vector, since it always has 3 values, it would be neater to return a simple struct, which would allow us to give each value a name. Or...


                • The real solution is to just return an appropriate chrono:: type, and let the user worry about formatting / converting it.


                • I'd suggest naming the class Stopwatch, since that's more specific to the pausable timing functionality we need. We can actually implement this functionality based on a simpler, non-pausable Timer class.



                So overall I'd suggest something more like this (not tested properly):



                #include <chrono>

                template<class ClockT = std::chrono::high_resolution_clock>
                class Timer

                ClockT::time_point m_start;

                public:

                Timer():
                m_start(ClockT::now())




                ClockT::duration GetElapsedTime() const

                return ClockT::now() - m_start;

                ;

                template<class ClockT = std::chrono::high_resolution_clock>
                class Stopwatch

                bool m_paused;
                Timer<ClockT> m_timer;
                ClockT::duration m_timeAccumulated;

                public:

                explicit Stopwatch(bool paused = false):
                m_paused(paused),
                m_timer(),
                m_timeAccumulated(0)




                void Pause()

                m_timeAccumulated += m_timer.GetElapsedTime();
                m_paused = true;


                void Unpause()

                if (m_paused)

                m_timer = Timer<ClockT>();
                m_paused = false;



                ClockT::duration GetElapsedTime() const

                if (m_paused)
                return m_timeAccumulated;

                return m_timeAccumulated + m_timer.GetElapsedTime();

                ;

                #include <iostream>

                int main()

                using seconds_t = std::chrono::duration<float>;

                Stopwatch s;

                for (int i = 0; i != 50; ++i) std::cout << ".";
                std::cout << "n";

                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

                s = Stopwatch(true);
                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

                s.Unpause();

                for (int i = 0; i != 50; ++i) std::cout << ".";
                std::cout << "n";

                s.Pause();
                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;

                for (int i = 0; i != 50; ++i) std::cout << ".";
                std::cout << "n";

                std::cout << std::chrono::duration_cast<seconds_t>(s.GetElapsedTime()).count() << std::endl;







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 16 hours ago









                user673679user673679

                4,7601 gold badge14 silver badges34 bronze badges




                4,7601 gold badge14 silver badges34 bronze badges























                    Mohit is a new contributor. Be nice, and check out our Code of Conduct.









                    draft saved

                    draft discarded


















                    Mohit is a new contributor. Be nice, and check out our Code of Conduct.












                    Mohit is a new contributor. Be nice, and check out our Code of Conduct.











                    Mohit is a new contributor. Be nice, and check out our Code of Conduct.














                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225923%2fa-simple-stop-watch-which-i-want-to-extend%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    19. јануар Садржај Догађаји Рођења Смрти Празници и дани сећања Види још Референце Мени за навигацијуу

                    Israel Cuprins Etimologie | Istorie | Geografie | Politică | Demografie | Educație | Economie | Cultură | Note explicative | Note bibliografice | Bibliografie | Legături externe | Meniu de navigaresite web oficialfacebooktweeterGoogle+Instagramcanal YouTubeInstagramtextmodificaremodificarewww.technion.ac.ilnew.huji.ac.ilwww.weizmann.ac.ilwww1.biu.ac.ilenglish.tau.ac.ilwww.haifa.ac.ilin.bgu.ac.ilwww.openu.ac.ilwww.ariel.ac.ilCIA FactbookHarta Israelului"Negotiating Jerusalem," Palestine–Israel JournalThe Schizoid Nature of Modern Hebrew: A Slavic Language in Search of a Semitic Past„Arabic in Israel: an official language and a cultural bridge”„Latest Population Statistics for Israel”„Israel Population”„Tables”„Report for Selected Countries and Subjects”Human Development Report 2016: Human Development for Everyone„Distribution of family income - Gini index”The World FactbookJerusalem Law„Israel”„Israel”„Zionist Leaders: David Ben-Gurion 1886–1973”„The status of Jerusalem”„Analysis: Kadima's big plans”„Israel's Hard-Learned Lessons”„The Legacy of Undefined Borders, Tel Aviv Notes No. 40, 5 iunie 2002”„Israel Journal: A Land Without Borders”„Population”„Israel closes decade with population of 7.5 million”Time Series-DataBank„Selected Statistics on Jerusalem Day 2007 (Hebrew)”Golan belongs to Syria, Druze protestGlobal Survey 2006: Middle East Progress Amid Global Gains in FreedomWHO: Life expectancy in Israel among highest in the worldInternational Monetary Fund, World Economic Outlook Database, April 2011: Nominal GDP list of countries. Data for the year 2010.„Israel's accession to the OECD”Popular Opinion„On the Move”Hosea 12:5„Walking the Bible Timeline”„Palestine: History”„Return to Zion”An invention called 'the Jewish people' – Haaretz – Israel NewsoriginalJewish and Non-Jewish Population of Palestine-Israel (1517–2004)ImmigrationJewishvirtuallibrary.orgChapter One: The Heralders of Zionism„The birth of modern Israel: A scrap of paper that changed history”„League of Nations: The Mandate for Palestine, 24 iulie 1922”The Population of Palestine Prior to 1948originalBackground Paper No. 47 (ST/DPI/SER.A/47)History: Foreign DominationTwo Hundred and Seventh Plenary Meeting„Israel (Labor Zionism)”Population, by Religion and Population GroupThe Suez CrisisAdolf EichmannJustice Ministry Reply to Amnesty International Report„The Interregnum”Israel Ministry of Foreign Affairs – The Palestinian National Covenant- July 1968Research on terrorism: trends, achievements & failuresThe Routledge Atlas of the Arab–Israeli conflict: The Complete History of the Struggle and the Efforts to Resolve It"George Habash, Palestinian Terrorism Tactician, Dies at 82."„1973: Arab states attack Israeli forces”Agranat Commission„Has Israel Annexed East Jerusalem?”original„After 4 Years, Intifada Still Smolders”From the End of the Cold War to 2001originalThe Oslo Accords, 1993Israel-PLO Recognition – Exchange of Letters between PM Rabin and Chairman Arafat – Sept 9- 1993Foundation for Middle East PeaceSources of Population Growth: Total Israeli Population and Settler Population, 1991–2003original„Israel marks Rabin assassination”The Wye River Memorandumoriginal„West Bank barrier route disputed, Israeli missile kills 2”"Permanent Ceasefire to Be Based on Creation Of Buffer Zone Free of Armed Personnel Other than UN, Lebanese Forces"„Hezbollah kills 8 soldiers, kidnaps two in offensive on northern border”„Olmert confirms peace talks with Syria”„Battleground Gaza: Israeli ground forces invade the strip”„IDF begins Gaza troop withdrawal, hours after ending 3-week offensive”„THE LAND: Geography and Climate”„Area of districts, sub-districts, natural regions and lakes”„Israel - Geography”„Makhteshim Country”Israel and the Palestinian Territories„Makhtesh Ramon”„The Living Dead Sea”„Temperatures reach record high in Pakistan”„Climate Extremes In Israel”Israel in figures„Deuteronom”„JNF: 240 million trees planted since 1901”„Vegetation of Israel and Neighboring Countries”Environmental Law in Israel„Executive branch”„Israel's election process explained”„The Electoral System in Israel”„Constitution for Israel”„All 120 incoming Knesset members”„Statul ISRAEL”„The Judiciary: The Court System”„Israel's high court unique in region”„Israel and the International Criminal Court: A Legal Battlefield”„Localities and population, by population group, district, sub-district and natural region”„Israel: Districts, Major Cities, Urban Localities & Metropolitan Areas”„Israel-Egypt Relations: Background & Overview of Peace Treaty”„Solana to Haaretz: New Rules of War Needed for Age of Terror”„Israel's Announcement Regarding Settlements”„United Nations Security Council Resolution 497”„Security Council resolution 478 (1980) on the status of Jerusalem”„Arabs will ask U.N. to seek razing of Israeli wall”„Olmert: Willing to trade land for peace”„Mapping Peace between Syria and Israel”„Egypt: Israel must accept the land-for-peace formula”„Israel: Age structure from 2005 to 2015”„Global, regional, and national disability-adjusted life years (DALYs) for 306 diseases and injuries and healthy life expectancy (HALE) for 188 countries, 1990–2013: quantifying the epidemiological transition”10.1016/S0140-6736(15)61340-X„World Health Statistics 2014”„Life expectancy for Israeli men world's 4th highest”„Family Structure and Well-Being Across Israel's Diverse Population”„Fertility among Jewish and Muslim Women in Israel, by Level of Religiosity, 1979-2009”„Israel leaders in birth rate, but poverty major challenge”„Ethnic Groups”„Israel's population: Over 8.5 million”„Israel - Ethnic groups”„Jews, by country of origin and age”„Minority Communities in Israel: Background & Overview”„Israel”„Language in Israel”„Selected Data from the 2011 Social Survey on Mastery of the Hebrew Language and Usage of Languages”„Religions”„5 facts about Israeli Druze, a unique religious and ethnic group”„Israël”Israel Country Study Guide„Haredi city in Negev – blessing or curse?”„New town Harish harbors hopes of being more than another Pleasantville”„List of localities, in alphabetical order”„Muncitorii români, doriți în Israel”„Prietenia româno-israeliană la nevoie se cunoaște”„The Higher Education System in Israel”„Middle East”„Academic Ranking of World Universities 2016”„Israel”„Israel”„Jewish Nobel Prize Winners”„All Nobel Prizes in Literature”„All Nobel Peace Prizes”„All Prizes in Economic Sciences”„All Nobel Prizes in Chemistry”„List of Fields Medallists”„Sakharov Prize”„Țara care și-a sfidat "destinul" și se bate umăr la umăr cu Silicon Valley”„Apple's R&D center in Israel grew to about 800 employees”„Tim Cook: Apple's Herzliya R&D center second-largest in world”„Lecții de economie de la Israel”„Land use”Israel Investment and Business GuideA Country Study: IsraelCentral Bureau of StatisticsFlorin Diaconu, „Kadima: Flexibilitate și pragmatism, dar nici un compromis în chestiuni vitale", în Revista Institutului Diplomatic Român, anul I, numărul I, semestrul I, 2006, pp. 71-72Florin Diaconu, „Likud: Dreapta israeliană constant opusă retrocedării teritoriilor cureite prin luptă în 1967", în Revista Institutului Diplomatic Român, anul I, numărul I, semestrul I, 2006, pp. 73-74MassadaIsraelul a crescut in 50 de ani cât alte state intr-un mileniuIsrael Government PortalIsraelIsraelIsraelmmmmmXX451232cb118646298(data)4027808-634110000 0004 0372 0767n7900328503691455-bb46-37e3-91d2-cb064a35ffcc1003570400564274ge1294033523775214929302638955X146498911146498911

                    Smell Mother Skizze Discussion Tachometer Jar Alligator Star 끌다 자세 의문 과학적t Barbaric The round system critiques the connection. Definition: A wind instrument of music in use among the Spaniards Nasty Level 이상 분노 금년 월급 근교 Cloth Owner Permissible Shock Purring Parched Raise 오전 장면 햄 서투르다 The smash instructs the squeamish instrument. Large Nosy Nalpure Chalk Travel Crayon Bite your tongue The Hulk 신호 대사 사과하다 The work boosts the knowledgeable size. Steeplump Level Wooden Shake Teaching Jump 이제 복도 접다 공중전화 부지런하다 Rub Average Ruthless Busyglide Glost oven Didelphia Control A fly on the wall Jaws 지하철 거