C++模板類繼承的一個小技巧


先說一下background
前段時間想實現一個Sqlite localstorage的功能,對應不同的Model 實體有不同的table, 每一次sql操作的函數簽名中會有model實體中的struct結構作為參數,struct完全不同,無法抽象,如何實現呢?

方式1:
每一次操作實現一個函數,如update table1(model struct1) / update table2(model struct2), 這樣實現也有好處,簡單明了,每個函數簽名代表了最最直接的操作,最后把所有的函數簽名集合到一個大文件中暴露出來即可,

所有數據庫的操作也只有該大文件一個入口; 缺點是每個函數中大量重復邏輯不好抽離,感覺有點Low。

方式2:

一旦覺得有重復邏輯,抽象就會自然而然萌生。簡單粗暴,重復邏輯抽離為單獨函數,這只是封裝的思想,不過確實也能解決一些問題,只是對該場景感覺用處不大。

再有就是抽離接口,抽象基類,找到共通點,這應該是大多數的想法,也是我寫程序經常思考的方式。但是又有問題,這些函數簽名都不同(model struct不同),override沒有意義,簡單的繼承根本解決不了問題。

方式3:

模板,這確實是一種抽象能力,往往要求更高(我是不太會用模板),大量的開源項目幾乎都是模板,似乎扯遠了。。。。

不同的model structk可以用模板來抽象,但是對應的處理邏輯又是不同的(突然想到了什么,咦,這不是虛函數干的事嗎),又回到了方式2的問題

方式2 & 方式3:

模板繼承,base中轉化為特定的子類,於是有了下面的代碼

template<typename TableType, typename RowType>
class SqliteTable
{
}


template<typename TableType, typename RowType>
template<typename KeywordType>
bool SqliteTable<TableType, RowType>::execDeleteRowByKeyword(CppSQLite3DB* sqliteDB, const std::string& columnName, const KeywordType& keyword)
{
	// convert base to child spefic instance
	return static_cast<TableType*> (this)->execDeleteRowByKeyword<KeywordType>(sqliteDB, columnName, keyword);
}

主要其實就是在父類中直接轉化為子類的對象,在編譯期就實現了多態,不同於虛函數的運行期  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM