C ++自定义“列表”实现不起作用

时间:2011-09-25 17:58:54

标签: c++ list

我尝试创建一个列表容器,在c ++中具有与C#中类似的元素访问权限 我现在完全迷失了,因为我的主要方法首先打印出奇怪的数字。

RList类应该是:

RList<ClassName or Primitive> VariableName;

VariableName.AddData(Class or Primitive);

VariableName[IndexOfElement] get the element

VariableName.RemoveAt(IndexOfElement) remove element

你能告诉我哪里出错吗?

int main()
{

RList<int> Numbers;

    Numbers.AddData(5);
    Numbers.AddData(100);
    Numbers.AddData(1500);

for (unsigned int x = 0; x < Numbers.GetLength(); x++)
{

    cout << Numbers[0] << endl;
}



cin.get();

return 0;
}

这是Header文件。我知道如果你使用模板,你必须把所有东西放在标题中。

#ifndef RList_H
#define RList_H

#include <new>


template <class T> class RList
{

 private:
    unsigned int m_Length;
    T* ListObject;

    void AllocateNew(T obj);
    void RemoveIndex(unsigned int N);

public:
    RList();
    ~RList();
    void AddData(T obj);
    void RemoveAt(unsigned int N);
    unsigned int GetLength() { return m_Length; }
    T operator[](unsigned int N){if (N < m_Length && N >= 0) {return (ListObject[N]);} return NULL; }


};

template <class T>
RList<T>::RList()
{

this->m_Length = 0;


}

template <class T>
RList<T>::~RList()
{

delete[] this->ListObject;


}

template <class T>
void RList<T>::AddData(T obj)
{
this->AllocateNew(obj);
this->m_Length++;

}

template <class T>
void RList<T>::RemoveAt(unsigned int N)
{
if( N < this->m_Length && N >= 0)
{
    if ((this->m_Length - 1) > 0)
    {
            this->RemoveIndex(N);
            this->m_Length--;
    }

    else
    {

    throw "Can't erase last index!";



    }


}



}

template <class T>
void RList<T>::AllocateNew(T obj)
{


if (this->m_Length == 0)
{
    this->ListObject[0] = obj;

}

else
{

T* NewListObject = new T [this->m_Length + 1];

for (unsigned int x = 0; x < this->m_Length; x++)
{
    NewListObject[x] = this->ListObject[x];

}

NewListObject[this->m_Length] = obj;

delete [] ListObject;
this->ListObject = NewListObject;

delete [] NewListObject;

}

}


template <class T>
void RList<T>::RemoveIndex(unsigned int N)
{
T* NewListObject = new T [this->m_Length - 1];
for (int x = 0; x < this->m_Length -1; x++)
{
    if (x != N)
    {

        NewListObject[x] = this->ListObject[x];

    }


}
delete [] ListObject;
this->ListObject = NewListObject;


}
#endif // RList_H

4 个答案:

答案 0 :(得分:2)

很多问题:

  1. 构造函数应初始化所有成员
  2. 三条规则未实施(在拥有指针上)。
  3. 可怕的间距(你需要更好地格式化代码)。
  4. 您的所有阵列内存分配都是错误的。
  5. 分配:

    template <class T>
    void RList<T>::AllocateNew(T obj)
    {
        if (this->m_Length == 0)
        {
            // This will not work as you have not allocated the area for ListObjects.
            // I don't think this is a special case. You should have allocated a zero
            // length array in the constructor then then else part would have worked
            // like normal when adding the first element.
            this->ListObject[0] = obj;
        }
        else
        {
            // OK good start
            T* NewListObject = new T [this->m_Length + 1];
    
            // Rather than do this manually there is std::copy
            for (unsigned int x = 0; x < this->m_Length; x++)
            {
                NewListObject[x] = this->ListObject[x];
            }
            NewListObject[this->m_Length] = obj;
    
           // Though unlikely there is a posability of an exception from a destructor.
           // So rather than call delete on a member you should swap the member and the
           // temporary. Then when the object is a good state you can delete the old one.
           delete [] ListObject;
           this->ListObject = NewListObject;
    
           // Definately do NOT do this.
           // as you have just stored this pointer into ListObject.
           // ListObject is now pointing at free'ed memory.
           delete [] NewListObject;    
    
           // So I would have done (for the last section
           //   std::swap(this->ListObject, NewListObject);
           //   ++this->m_Length;
           //   // now we delete the old data
           //   delete [] NewListObject; // (remember we swapped above)
        }
    }
    

    RemoveIndex

    template <class T>
    void RList<T>::RemoveIndex(unsigned int N)
    {
        T* NewListObject = new T [this->m_Length - 1];
        for (int x = 0; x < this->m_Length -1; x++)
        {
            if (x != N)
            {
                // You need to compensate for the fact that you removed one
                // element (otherwise you have a hole in your new array).
                NewListObject[x] = this->ListObject[x];
            }
        }
    
        // Same comment as above.
        // Do not call delete on a member.
        // Make sure the object is a good state before doing dangerous stuff.
        delete [] ListObject;
        this->ListObject = NewListObject;
    }
    

答案 1 :(得分:1)

if (this->m_Length == 0)
{
    this->ListObject[0] = obj;
}

您必须先分配ListObject才能执行此操作。

注意:您的实施存在许多问题,您应将其发布到codereview,或查看书籍以了解如何实施正确的向量

答案 2 :(得分:0)

你遇到了很多问题,但是这个肯定会让你的程序崩溃:

(在AllocateNew末尾):

this->ListObject = NewListObject;
delete [] NewListObject;

现在,this->ListObject指向已被释放的内存。

答案 3 :(得分:0)

  

你能告诉我哪里出错吗?

你正在重新发明STL矢量类。您可以在其周围编写一个包装器来提供所需的API,但是按原样使用该类可能更容易。你的例子看起来像这样:

#include <iostream>
#include <vector>

using namespace std;

int main( )
{
  vector< int > Numbers;

  Numbers.push_back( 5 );
  Numbers.push_back( 100 );
  Numbers.push_back( 1500 );

  for ( unsigned int x = 0; x < Numbers.size( ); x++ )
  {
    cout << Numbers[x] << endl;
  }

  cin.get();

  return 0;
}