首页 > 编程语言 >OCC集合类 NCollection_Array1源码解析

OCC集合类 NCollection_Array1源码解析

时间:2022-11-29 13:45:14浏览次数:42  
标签:const NCollection myData OCC int 源码 theOther TheItemType return

// 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的元素(可能为“野指针”)

};

标签:const,NCollection,myData,OCC,int,源码,theOther,TheItemType,return
From: https://www.cnblogs.com/06NN08/p/16935177.html

相关文章