openFoam源码中的C++
openFoam源碼中涉及到的c++思想有很多,因為在計算流體力學中,域的創建尤為重要,我們可以在域中存儲我們想要的物理變量如速度、壓力等等。
首先:有一個宏觀上的思維,我們用的大多數域對應的C++類是GeometricField,這個類里面包含了很多信息,但他的Base類其實是Field這個類,可以用下圖來表示這個關系:
分析
當然,一切要從代碼看起:
首先看Field基類,找到Filed的.C和.H頭文件開始分析:
該類都是在Foam這個大的命名空間底下,下面定義了很多模板類。
這里用到了很多模板類的語法,首先聲明了兩個模板類的前置聲明Field以及SubField,在這里要注意的是為什么要進行前置聲明:
由于某些原因不方便在頭文件中直接引入另一個模板類的頭文件,但聲明變量是需要用到該模板類型,這時候就要用到模板類的前置聲明
可以看到操作符重載的參數列表里用到了Field<Type>,這就必須進行前置聲明,可能此時大家又有疑問,為什么操作符的重載也要進行前置聲明呢,這是可以看到在Filed這個大的模板類里有這樣一段友元函數的聲明:
有這樣一條規定:友元函數和運算符的前向聲明:如果一個模板類里調用了友元函數(外面定義的方法可以使用該類里面的私有變量),而且這個友元函數里面的參數還用到了這個模板類,那么就得提前以模板的方式去聲明這個類和函數。
這樣大家就懂了頭文件里前面這幾行的聲明的必要性。下面再看這個Filed類模板里面的一些難以理解的C++代碼。
首先我們看到這里的Filed繼承了List,相當于我們的Filed里面存儲方式為一維數組的存儲。
下面定義了一個copy函數:
這里看到前后都有一個const:前面的const好理解說明這個指針不能被改變,最后這const用于修飾該函數,表示在函數內不能改變其對應對象的成員變量的值。
接下來的typedef是用來聲明兩個類型的,第一個typename的作用是給編譯器強調后面跟的是一個類型。
下來該類又使用了一個內聯函數, 為了解決一些頻繁調用的小函數大量消耗棧空間(棧內存)的問題,特別的引入了 inline 修飾符,只是建議內聯不代表編譯器真的會執行
inline static const Field<Type>& null(){return NullObjectRef<Field<Type>>();}下來定義了一些該類的構造器,其中比較有意思的是:
explicit Field(const label);這里explict的解釋我總結如下:
C++中的explicit關鍵字只能用于修飾只有一個參數的類構造函數,
它的作用是表明該構造函數是顯示的, 而非隱式的, 跟它相對應的
另一個關鍵字是implicit, 意思是隱藏的,類構造函數默認情況下即聲明為
implicit(隱式).explicit聲明之后,外面調用該構造函數必須顯式聲明,
因為構造器若只有一個參數并且默認是implicit,在外面調用的時候可以直接等于…,
編譯器會自動給你補全,這樣很容易產生歧義
例子:
A(int size){
…構造函數里面的變量
}
外面調用可以直接A = 10;但是這個10并不代表size,不倫不類
接下來,該類還使用了一些復制構造函數,這都是我們平常開發不經常使用的操作:
復制構造函數的解釋:
如果類的設計者不寫復制構造函數,
編譯器就會自動生成復制構造函數。
大多數情況下,其作用是實現從源對象到目標對象逐個字節的復制,
即使得目標對象的每個成員變量都變得和源對象相等。
在.C文件中,我們也可以看見一些有意思的寫法,比如說模板構造函數,成員變量的直接初始化等等:
看懂了這個文件,在相應的找到DimensionedField和GeometricField就可以看出他們之間的繼承和每次繼承完以后新添的一些功能創造出了一個GeometricField這樣包含很多信息的域類。
總結
以上是生活随笔為你收集整理的openFoam源码中的C++的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手把手教你在windows10下进行op
- 下一篇: 通过OpenFoam记录一些c++的tr