0

我试图为 C++ 制作我自己的列表。我有这个类:

template <class T>
class List
{
private:
T *value, *valueHelper;
int valueSize;

 public:
int size;

List()
{
    valueSize = 2;
    value = (T*)malloc(sizeof(T) * valueSize);
    size = 0;
}


void Add(T val)
{
    size++;

    if (size > valueSize)
    {
        valueSize *= 2;
        valueHelper = (T*)malloc(sizeof(T) * valueSize);

        memcpy(valueHelper, value, sizeof(T) * (valueSize / 2));
        free(value);
        value = valueHelper;;
    }

    value[size - 1] = val;

}

T operator[](int P)
{
    return value[P];
}

};

当我尝试主要使用它时,它对 Int 工作正常。Buy to Struct 有问题:

struct Material
{
string materialName;
int faceNum;
int meshNum;

Material(): materialName(""), faceNum(0), meshNum(0){};
};


void main() 
{
    List <Material> myList = List<Material>();
    myList.Add(Material());
}

我在线上的类中遇到运行时错误:

value[size - 1] = val;

为什么?

4

2 回答 2

1

您的代码中至少有两个错误:

- you cannot use memcpy to move class memory from one place to another except in very few cases. a std::string is not one of these cases.
- When you call an operator= it needs that the receiver is well formed, and it means that it is construct.

您遇到了第二个错误,因为 value[0] 永远不会构造,当您调用 operator= 时,它充满了垃圾,并且很可能尝试删除随机指针值。

我想您更喜欢仅在需要时构造对象,就像 std::vector 一样?所以更好的实现是:

template <class T>
class List {
    int m_size;
    int m_capacity;
    T * m_elems;

    public:
    List() : 
        m_size(),
        m_capacity( 2 ),
        m_elems( (T*) malloc( sizeof(T) * m_capacity ) ) {
    }

    void Add( T const & val ) {
        if ( m_size + 1 > m_capacity ) {
            m_capacity *= 2;
            T * elems = (T*) malloc( sizeof(T) * m_capacity );

            for( int i = 0 ; i != m_size ) {
                new ( elems + i ) T( m_elems[i] ); // copy constructor
                ( m_elems + i )->~T(); // manually call the destructor
            }
            free( m_elems ); 
            m_elems = elems;
        }
        new( m_elems + m_size++ ) T( val );
    }

    T operator[](int P) {
        assert( P < m_size );
        return m_elems[P];
    }
};
于 2013-08-25T09:00:58.987 回答
0

这是因为我没有注意您原始代码中的第三个错误!operator[] 需要按引用返回,而不是按值返回。

T & operator[](int P) {
    assert( P < m_size );
    return m_elems[P];
}

你可能也想要 const 版本

T const & operator[](int P) const {
    assert( P < m_size );
    return m_elems[P];
}
于 2013-08-25T10:17:16.077 回答