以PHP觀點來看 C++ template
在從 C++ Template 到 Java Generic,一步一步來一文,我用 Java 的泛型語法改寫了一個 C++ 樣板類別。 我也用 PHP、JavaScript 和 Ruby 來做同樣的事,看看這些動態語言有沒有泛型處理能力。
我要用 PHP 改寫的 C++ 樣板類別,其源碼同從 C++ Template 到 Java Generic,一步一步來。本文不再重複,直接說明 PHP 的改寫過程。
PHP 改寫過程
PHP 的類別定義語法和 C++/Java 差異不大(其實是像Java)。
Cx
是個樣板類別,定義中使用的型別為參數化、可替換者。
在 PHP 中的意義,就代表著不具體的型別,通常就是用 var
或不寫。
PHP 的變數都是用 $ 開頭,存取資料成員時一定要用 $this 指示,不可省略。
方法定義要加關鍵字 function
,略去參數與回傳值的型別。
PHP 的建構子有兩種寫法:
- 舊式(PHP4)跟 C++/Java 一樣,跟類別同名的方法即為建構子。
- 新式(PHP5)則統一名稱為
__construct
。
本例兩種都用。
Cx 有兩個建構子,一個是無參數的預設建構子,另一個是一個參數的建構子。PHP 可以用參數預設值的方式簡化建構子的改寫動作,寫成一個。其實 C++ 就可以用參數預設值的方式將兩個建構子寫成一個建構子。 只是因為 Java, JavaScript 不支援參數預設值,所以我的 C++ 程式碼才特意分開來寫。
緊接著上面的內容,接著的要改寫 C++ 的 main()
。在 PHP 中不需要指示程序進入點,直接寫即可。
PHP 的變數不用宣告型別,由右值的實體決定左值的型別。 C# 3.0 引入了類似觀念。但是 PHP 的變數可以再次指派其他型別的資料給左值;C# 3.0 則在第一次指派後便固定型別,之後不可指派其他型別的內容給變數。
在 C++ 中的樣板類別 Cx ,到了 PHP 之後,跟一般的類別沒兩樣。雖然 PHP 的語法很像 C++, Java ,但至少它還算是動態語言,故其語義基本上仍是泛型的。
有些沒接觸過動態語言的人,對於泛型有一種奇怪的誤解,他們認為動態語言並沒有泛型語法,所以動態語言沒有泛型能力。我在C++和動態語言的泛型一文中曾經駁斥過這一論點。從語意看,動態語言其實就是泛型的。
移除 C++ 型別資訊,以 PHP 語法改寫的 N, M, S 類別定義,也僅僅只剩兩行程式碼不同,這意味著我們可以進一步重構彙整。 而 PHP5 的新式建構子寫法此時也看得出一個好處,就是名稱統一,重構類別時不必再去修改建構子的名稱。