C++如何完成復雜的計時器詳解。本站提示廣大學習愛好者:(C++如何完成復雜的計時器詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C++如何完成復雜的計時器詳解正文
完成剖析
首先我們先剖析一下計時器的一些功用,復雜一點的計時器包括開端、暫停、中止和顯示根本功用,這些功用以C++面向對象的編程思想(OOP)停止籠統,就是計時器類(Timer)的4個成員函數,當然我們要把這些函數作為私有的,由於它們是留給內部的接口(interface)。
然後我們再剖析一下計時器的三種形態:中止,正在運轉,暫停(留意:暫停不是中止),那麼怎樣記載計時器的三種形態呢?
這裡我們用布爾類型的變量記載計時器的三種形態,辨別為bool is_pause,bool is_stop,在這裡一定要留意變量的命名,好像這樣見名知意。吐舌頭當然為了表現C++類的封裝性,要把這兩個bool變量作為計時器類(Timer)的公有成員。
完成辦法
重要的問題來了,我們怎樣完成計時呢?吶,你們知道time()
函數嗎?復雜的說一下time函數:這個函數在time.h頭文件中,它前往自 Unix 紀元(January 1 1970 00:00:00 GMT)起的以後時間的秒數,是一個長整形(long)。這樣我們在計時器開端的時分獲取一個time函數的前往值,保管到一個變量中,在用一個變量保管暫停時的時間。當我們開端計時的時分,進入一個死循環,一直用time()
-開端的時間,就是以後計時器的時間。(不要急,詳細完成往下看)。此時為了保管開端和暫停時辰的時間,必需在計時器類(Timer)中添加兩個長整形(long)變量:start_time,pause_time,當然作為公有變量。
仿佛還少點什麼......為了讓內部獲取以後計時器的形態,我們還需求兩個函數前往計時器的形態,is_pause()
計時器能否處於暫停,is_stop()
計時器能否處於中止形態,前往值的類型為bool。
詫異別忘了Timer的結構函數,用來做一些初始化的任務!
好了,至此我們的計時器類設計完成了(prefect),代碼在上面:
class Timer { private: long start_time; long pause_time; //兩個bool值標志四種形態 bool is_pause; //記載計時器的形態 (能否處於暫停形態) bool is_stop;//能否處於中止形態 public: Timer(); bool isPause(); //前往計時器形態 bool isStop(); //計時器的三種舉措(功用) void Start(); void Pause(); void Stop(); inline long getStartTime() {return start_time;} void show(); };
接上去的義務就是完成Timer的成員函數了..............
首先是結構函數Timer::Timer()
,完成一些初始化的任務:
Timer::Timer() { is_pause = false; //初始化計時器形態 is_stop = true; }
計時器開端計時之前應該處於中止形態!(計時器只能處於一種形態,不要犯懵懂哦!)
成員函數isPause()
它的作用僅是讓內部獲取計時器能否處於暫停形態,so easy
bool Timer::isPause() { if(is_pause) return true; else return false; }
isStop函數和isPause一樣只是一個接口,讓內部獲取計時器的形態:
bool Timer::isStop()
{
if(is_stop)
return true;
return false;
}
上面是Timer::Start()
函數的完成,它是計時器開端的時分要運轉的函數:
void Timer::Start() //開端 { if(is_stop) { start_time = time(0); is_stop = false; } else if(is_pause) { is_pause = false; start_time += time(0)-pause_time; //更新開端時間:用此時的時間 - 暫停時所用的時間 + 上一次開端的時間 = 此時的開端時間 } }
我們首先判別一下計時的形態,假如處於中止形態,獲取開端的時間,然後更新計時器的形態;假如計時器正處在暫停形態,我們讓計時器持續計時,我采用改動開端的計時的時間(start_time)去調整計時的時間 : (用此時的時間 - 暫停時所用的時間 + 上一次開端的時間 = 此時的開端時間)。假如計時器正處於運轉形態,就什麼也不做!(不知道大家能不能看的懂.....)
這是暫停函數Timer::Pause()
的完成:
void Timer::Pause() //暫停 { if(is_stop||is_pause) //假如處於中止/暫停形態,此舉措不做任何處置,直接前往 return; else //否則調制為暫停形態 { is_pause = true; pause_time = time(0); //獲取暫停時間 } }
假如沒有在運轉,也就是處於暫停或中止形態,什麼也不做直接前往。否則就去處置暫停懇求:既然我們停止了暫停的操作,就要改動計時器的形態,將形態設置為暫停,保管此刻的時間,(這個暫停的時間pause_time在下面的開端的函數中用的到!)。
接著我們去完成中止函數Timer::Stop():
void Timer::Stop() //中止 { if(is_stop) //假如正處於中止形態(不是暫停形態),不做任何處置 return ; else if(is_pause) //改動計時器形態 { is_pause = false; is_stop = true; } else if(!is_stop) { is_stop = true; } }
假如處於中止形態,直接前往。否則假如處於暫停形態改動計時器的形態為is_stop = true
;否則就是處於運轉形態,直接改動計時器的形態為中止。
上面是顯示時間的函數Timer::show()
:
void Timer::show() { long t = time(0) - start_time; gotoxy(35,12); cout<<setw(2)<<setfill('0')<<t/60/60<<":" <<setw(2)<<setfill('0')<<t/60<<":" <<setw(2)<<setfill('0')<<t%60<<endl; }
這裡我要說一下gotoxy(int x,int y)
函數,它的作用是將控制台的光標定位到坐標(x,y)處,show函數是要放到死循環中的,所以這樣一直將輸入的時間打印到一個中央,完成了時間的更新(我是不是很聰明);setw(int x)
是設置輸入的字寬,setfill(char ch)
設置了字符的填充。time函數前往的是秒數,t/60/60失掉小時,t/60失掉分鐘,t%60失掉秒數。
上面就是主函數了main()
int main() { Timer t; char ch; hidden();//隱藏光標 system("color 02"); gotoxy(35,12); cout<<"00:00:00"; gotoxy(20,18); cout<<"按a開端,按空格暫停,按s中止"; while(1) { if(kbhit()) { ch = getch(); switch (ch) { case 'a':t.Start();break; case 's':t.Stop();break; case ' ':t.Pause();break; default :break; } } if(!t.isStop()&&!t.isPause()) { t.show(); } } }
Timer t;定義一個計時器。hidden()
;是用來隱藏控制台光標的,不是必需的。
然後是進入死循環,kbhit()
函數是檢測能否有按鍵,如有按鍵前往非0值,沒有按鍵前往0;用getch()
獲取按鍵,然後用
switch case分支構造處置不同的按鍵。
至此,我們的計時器設計完成!是不是覺得很復雜啊!吐舌頭
讓我們看一下運轉後果:
上面是本順序用到的頭文件:
#include <iostream> #include <cstdlib> #include <ctime> #include <conio.h> #include <iomanip> #include <windows.h>
上面是代碼中用到的函數:
void gotoxy(int x,int y)
void gotoxy(int x, int y)//定位光標,x為行坐標,y為列坐標 { COORD pos = {x,y};//(坐標 地位); HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //失掉規范處置(規范輸入處置); SetConsoleCursorPosition(hOut, pos);//設置控制台光標地位; }
void hidden( )
void hidden()//隱藏光標 { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(hOut,&cci); cci.bVisible=0;//賦1為顯示,賦0為隱藏 SetConsoleCursorInfo(hOut,&cci); }
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或許能帶來一定的協助,假如有疑問大家可以留言交流。