construct 到 base class 時,C++ 視該 object 為 base class object,derived class 的 virtual function 跟 member 都還沒建出來,所以 call 不到 derived class 的 virtual function。
反過來的 destruct 則是在 derived class destructor 跑完後,derived class 的東西都刪光光了,該 object 就被當作 base class object,所以在 base class destructor 裡 call virtual function 不會 call 到 derived class 的 virtual function。
不能修改 class non-static member data 也不能 call 其他非 const member function 的 member function。
宣告 function 時在最後面加個 const 的 function,ex:
1
intGetIndex()const;
Declaring a member function with the const keyword specifies that the function is a “read-only” function that does not modify the object for which it is called. A constant member function cannot modify any non-static data members or call any member functions that aren’t constant.
compiler 會檢查 const member function 是否有改到 member data、return value 是否為 pointer 或 reference,如果改到 member data 或傳回可以讓外界修改 member data 時 compiler 會 error。可以透過這個特性反向檢查一個原本非 const 的 member function 是否有修改到 member data。
如果要在 const member function 中修改特定 member data,可以在該 member data 的宣告前面加上 mutable。
PHPUnit 在一些系統上會有 header already sent 的錯誤,加 --stderr 可以避免 PHPUnit 把這視為測試錯誤。
執行單一測試,指定某測試檔做測試。
1
$ phpunit --stderr <test file path>
Basic conventions
class “Class” 的 test 放在 class “ClassTest”
ClassTest 要繼承 PHPUnit_Framework_TestCase
test 為 public method,method name 為 test*
在 test 中,用 assert*() function check value 是否符合預期
failure vs error
failure 是 assertion function fail(要測試的 function 的 output 不符合預期)。以 F 代表。
error 是出現 unexpected exception 或 PHP error。以 E 代表。
setUp() & tearDown()
為了讓測試是正確且獨立的,要保持執行 test 時環境是乾淨的。在每次執行一個 test method 前會 call setUp() 建立 test 所需要的 object、變數等等。run 完 test method 後會 call tearDown() 清東西。
通常只需 implement tearDown(),用來 close file、socket 等。
用 file system 組合 test suite
可以用 file system 的 directory structure 達到組合出一個 test suite 的目的。這也是最簡單的方式。:)
建立一 test dir 並建立跟 project dir 中一樣的 directory structure。把 test case source file(就是 test method 的 source code)以相應 project source file 的位置放進去。PHPUnit 會自動 traverse test dir 做 test。
舉例說明:
這是 project directory:
1 2
object/ MyStack.php
這是 test directory:
1 2
tests/ MyStackTest.php
PHPUnit 會在 test dir(上例的 tests/)底下找 *Test.php 來做測試。
執行 test suite
1
$ phpunit --stderr <test dir path>
寫 test 就是…
生一些 testcase(input 及預期的 output)
在 test method 裡 call 要測的 function,把 test case 的 input 當作 arg 丟進去。
A condition (short for ``condition variable’’) is a synchronization device that allows threads to suspend execution and relinquish the processors until some predicate on shared data is satisfied. The basic operations on conditions are: signal the condition (when the predicate becomes true), and wait for the condition, suspending the thread execution until another thread signals the condition.
A condition variable must always be associated with a mutex, to avoid the race condition where a thread prepares to wait on a condition variable and another thread signals the condition just before the first thread actually waits on it.
condition variable 必須搭配 mutex,避免 race condition:thread A 在 thread B signal condition 後才 wait 這個 condition variable,這種狀況可能讓 thread A 永遠在 sleep(如果沒有人會再 signal 這個 condition variable)。
為有「多型」性質(即有 virtual function)的 base class 宣告 virtual destructor。
C++ 沒有定義 base class 的 destructor 是 non-virtual 時以 base class pointer 刪除 derived class 的 object 的行為。常出現的結果是只有 base class 部分的 memory 會被釋放、derived class 部分的不會釋放,這會造成「局部銷毀」物件的問題,memory 當然就沒 free 乾淨。
用 virtual destructor 可以解決上述問題,因為 virtual function 的性質會 call 到 derived class 的 destructor。
不過不是把所有 base class 的 destructor 宣告成 virtual 就好,非必要(沒有 virtual function)時不需要這麼宣告。