0

タイトルが示すように、要素を消去した場合、そのようにstd :: vectorクラスを拡張しようとしますが、位置の値は消去されませんが、実際にはNULLに設定されます(ギャップを提供します)。

template<typename T>
class FVector : public std::vector<T> {
    typedef std::vector<T> Base;

protected:
    /** The number of elements in the vector */
    size_t elementCount;

    /**
     * The index of the last element. This field is actually vector's length. 
     * For example when you have a vector like this ["a","b","c"] then the 
     * elementCount would be 3 and lastIndex would be 2 (because indexes are 
     * zero-based). But if you erased two first elements, 
     * leaving [null, null, "c" ] then elementCount=1 (because there is only 
     * one element in the vector!) however lastIndex would still remain 2. 
     * After you erase "c" lastIndex would be set to -1 (so it's enough to 
     * add 1 to lastIndex to determine vector's length.
     */
    int lastIndex;

private:
    /**
     * Returns the index of the last not-null element in the vector, 
     * starting from position position downwards.
     *
     * @param position the position from which counting is to be begun.
     * @return last element before (or on) index <code>position</code>
     */
    int FindLastIndex(int position) {
        int nLastItem = position;

        if (position < 0) {
            return -1;
        }

        for (; nLastItem >= 0; nLastItem--) {
            if (Base::operator[](nLastItem) != NULL) {
                break;
            }
        }

        return (nLastItem);
    }

public:

    FVector(const T & value = T())
    : elementCount(0), lastIndex(-1) {
    }

    FVector(int initialCapacity, const T & value = T())
    : elementCount(0), lastIndex(-1),
      std::vector<T>(initialCapacity, value) {
    }

    size_t Capacity() const {
        return Base::size();
    }

    size_t Size() const {
        return elementCount;
    }

    int LastIndex() const {
        return lastIndex;
    }

    void AddElement(const T& obj) {
        Base::push_back(obj);

        elementCount++;
        lastIndex++;
    }

    T & ElementAt(int index) {
        if (index > lastIndex) {
            // error
        }

        return Base::at(index);
    }
    void EraseElementAt(int index) throw() {
        if (index > lastIndex) {
            std::stringstream ss;
            ss << index << " > " << lastIndex;
            throw ArrayIndexOutOfBoundsException(ss.str());
        }

        if (Base::operator[](index) != NULL) {
            elementCount--;
            T v = Base::at(index);
            delete v;
            Base::at(index) = NULL;

            if (index == lastIndex) {
                lastIndex = FindLastIndex(lastIndex - 1);
            }
        }
    }
};

思ったように動作していません。要素でerase()メソッドを呼び出すと、要素はNULLに設定されません。

例えば:

class Int {
    int i;
public:
     Int(int v): i(v) { };
     ~Int() { }
};

//... 

FVector<Int *> * v = new FVector<Int *>();

v->AddElement(new Int(1));
v->AddElement(new Int(3));
v->AddElement(new Int(5));
v->EraseElementAt(0);
v->EraseElementAt(2);

// ...

delete v;

結果として

[null、3]

でもそうなると思います

[null、3、null]

まあ、それが私が達成しようとしていることが可能かどうかはわかりません。動的配列であるstd::vectorクラスを使用すると(なぜ独自の配列クラスを作成する必要があるのか​​)、そのようなものを実装するために必要なすべての基本が得られると思いました。

誰かがそれに光を当てることができますか、私はここでいくつかの実装の問題があると思います。

ご協力いただきありがとうございます!

4

1 に答える 1

3

EraseElementAtには、次のものがあります。

        if (index == lastIndex) {
            lastIndex = FindLastIndex(lastIndex - 1);
        }

ベクトルの最後の要素を(実行したときに)消去すると、ベクトルが短くなります(lastIndexをデクリメントします)。ベクトルにこれを行わせたくないようです。むしろ、ベクトルをnullにしたいが、短縮したくないようです。たぶんこれを取り出してください。

于 2012-07-06T15:39:54.820 に答える