OCC集合類 NCollection_Array1原始碼解析
// NCollection_Array1是一個模板類,容器類是模板類我們對這應該很熟悉了,畢竟為所有型別單獨寫一個容器類是不現實也沒必要的。
// 元素記憶體是順序儲存的,類似vector
// 此類中有一個顛覆我思想的操作,特此記錄。在上學、培訓時老師都教我們程式中不能有野指標,但此類正是通過“野指標”實現了任意範圍的控制。跳出固定思維很重要啊。
// 此類的範圍是閉區間 [a,b]
template <class TheItemType>
class NCollection_Array1
{
public:
// 值型別重定義,目的不詳。原始碼註釋:和STL定義保持一致
typedef TheItemType value_type;
public:
// 迭代器類定義
class Iterator
{
};
public:
NCollection_Array1()
: myLowerBound(1), myUpperBound(0), myDeletable(false), myData(nullptr)
{}
NCollection_Array1(const int theLower, const int theUpper)
: myLowerBound(theLower), myUpperBound(theUpper), myDeletable(true)
{
// 輸入有效性判斷,不合理拋異常。後續不再記錄常規異常處理程式碼
Standard_RangeError_Raise_if(xxx);
// 申請記憶體
TheItemType *pBegin = new TheItemType[Length()];
// 顛覆本人固有邏輯的操作。有效地址為pBegin,使myData指向無效但可控的0下標地址。
myData = pBegin - theLower;
}
NCollection_Array1(const NCollection_Array1 &theOther)
: myLowerBound(theOther.Lower()), myUpperBound(theOther.Upper()), myDeletable(true)
{
TheItemType *pBegin = new TheItemType[Length()];
myData = pBegin - myLowerBound;
Assign(theOther);
}
// 通過現有資料(通常是C形式陣列)構造,不負責記憶體管理(myDeletable=false)
NCollection_Array1(const TheItemType &theBegin, const int theLower, const int theUpper)
:myLowerBound(theLower), myUpperBound(theUpper), myDeletable(false)
{
myData = (TheItemType *)&theBegin - theLower;
}
// theValue覆蓋所有現有資料
void Init(const TheItemType &theValue)
{
TheItemType *pCur = &myData[myLowerBound],
*pEnd = &myData[myUpperBound];
for (; pCur <= pEnd; pCur++)
*pCur = (TheItemType &)theValue;
}
// 集合中元素數量查詢
int Size() const { return Length(); }
int Length() const { return myUpperBound - myLowerBound + 1; }
bool IsEmpty() const { return myUpperBound < myLowerBound; }
int Lower() const { return myLowerBound; }
int Upper() const { return myUpperBound; }
// 判斷資料是否需要被釋放
bool IsDeletable() const { return myDeletable; }
bool IsAllocated() const { return myDeletable; }
// 拷貝theOther中資料。要求兩容器中元素個數相同
NCollection_Array1 &Assign(const NCollection_Array1 &theOther)
{
if (&theOther == this) return *this;
if (nullptr == myData) return *this;
TheItemType *pMyItem = &myData[myLowerBound];
TheItemType *const pEndItem = &(theOther.myData)[theOther.myUpperBound];
TheItemType *pItem = &(theOther.myData)[theOther.myLowerBound];
// * 和 ++運算子優先順序
while(pItem <= pEndItem) *pMyItem++ = *pItem++;
return *this;
}
// 把theOther記憶體中資料移動過來,移動後,theOther仍可以讀取,但是不負責資料的儲存了
NCollection_Array1 &Move(NCollection_Array1 &theOther)
{
if (&theOther == this) return *this;
if (myDeletable) delete []&myData[myLowerBound];
myLowerBound = theOther.myLowerBound;
myUpperBound = theOther.myUpperBound;
myDeletable = theOther.myDeletable;
myData = theOther.myData;
theOther.myDeletable = false
return *this;
}
NCollection_Array1 &operator =(const NCollection_Array1 &theOther)
{
return Assign(theOther);
}
const TheItemType &First() const { return myData[myLowerBound]; }
TheItemType &ChangeFirst() { return myData[myLowerBound]; }
const TheItemType &Last() const { return myData[myUpperBound]; }
TheItemType &ChangeLast() { return myData[myUpperBound]; }
const TheItemType &Value(const int theIndex) const { return myData[theIndex]; }
const TheItemType &operator [](const int theIndex) const { return Value(theIndex); }
TheItemType &ChangeValue(const int theIndex) { return myData[theIndex]; }
TheItemType &operator ()(const int theIndex) { return ChangeValue(theIndex); }
TheItemType &operator [](int theIndex) { return ChangeValue(theIndex); }
void SetValue(int theIndex, const TheItemType &theItem) {myData[theIndex] = theItem; }
// 重置邊界。
// 如果新的長度和之前長度相等,則僅改變theLower, theUpper
// 如果theToCopyData為true,則會拷貝原有的資料,拷貝的資料個數為前、後長度的較小值
void Resize(const int theLower, const int theUpper, const bool theToCopyData)
{
const int anOldLen = Length();
const int aNewLen = theUpper - theLower + 1;
TheItemType *aBeginOld = nullptr != myData ? &myData[myLowerBound] : nullptr;
myLowerBound = theLower;
myUpperBound = theUpper;
if (aNewLen == anOldLen)
{
myData = aBeginOld - theLower;
return;
}
if (!theToCopyData && myDeletable) delete []aBeginOld;
TheItemType *aBeginNew = new TheItemType[aNewLen];
myData = aBeginNew - theLower;
if (!theToCopyData)
{ myDeletable = true; return;}
const int aLenCopy = Min(anOldLen, aNewLen);
for (int anIter = 0; anIter < aLenCopy; ++anIter)
aBeginNew[anIter] = aBeginOld[anIter];
if (myDeletable) delete []aBeginOld;
myDeletable = true;
}
~NCollection_Array1()
{
if (myDeletable) delete []&(myData[myLowerBound]);
}
protected:
int myLowerBound;
int myUpperBound;
bool myDeletable;
TheItemType *myData; // 指向下標為0的元素(可能為“野指標”)
};