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

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

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

全部數據庫的操做也只有該大文件一個入口; 缺點是每一個函數中大量重複邏輯很差抽離,感受有點Low。ide

方式2:函數

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

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

方式3:sqlite

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

不一樣的model structk能夠用模板來抽象,可是對應的處理邏輯又是不一樣的(忽然想到了什麼,咦,這不是虛函數乾的事嗎),又回到了方式2的問題blog

方式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);
}

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

相關文章
相關標籤/搜索