我已经尝试为 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];
}
};
当我尝试在 main 中使用它时,它对 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;
为什么?
最佳答案
您的代码中至少有两个错误:
- 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];
}
};
关于我的类中的 C++ 运行时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18426977/