我正在尝试实现我的自定义动态数组,例如 std::vector。
动态数组模块代码:
#ifndef ARRAY_H
#define ARRAY_H
#include <cstdlib>
#define CAPACITY_SCALE_FACTOR 2
template <typename T>
struct Array
{
T* data;
size_t size;
size_t capacity;
Array()
{
size = 0;
capacity = 10;
data = (T*)malloc(capacity * sizeof(T));
}
~Array()
{
free(data);
data = NULL;
size = capacity = 0;
}
T& operator[](size_t index);
const T& operator[](size_t index) const;
Array(const Array &other){
if (array_size(other))
for (size_t i = 0; i < other.size; i++)
array_insert(*this, other[i]);
}
Array& operator=(const Array& other) {
if (array_size(other))
for (size_t i = 0; i < array_size(other); i++)
array_insert(*this, other[i]);
return *this;
}
};
template <typename T>
T& Array<T>::operator[](size_t index)
{
return data[index];
}
template <typename T>
const T& Array<T>::operator[](size_t index) const
{
return data[index];
}
template <typename T>
size_t array_size(const Array<T> &array)
{
return array.size;
}
template <typename T>
void array_insert(Array<T> &array, const T value)
{
array[array.size] = value;
array.size++;
if (array.size == array.capacity)
{
array.capacity *= CAPACITY_SCALE_FACTOR;
array.data = (T*)realloc(array.data, array.capacity * sizeof(T));
}
}
template <typename T>
void array_delete(Array<T> &array, size_t index)
{
for (size_t i = index; i < array.size - 1; i++)
{
array[i] = array[i + 1];
}
array.size--;
if ( array.size <= ( array.capacity / (CAPACITY_SCALE_FACTOR * 2) ) )
{
array.capacity =
(array.size == 0) ? 1 : array.size * CAPACITY_SCALE_FACTOR;
array.data = (T*)realloc(array.data, array.capacity * sizeof(T));
}
}
#endif
使用示例代码:
#include "array.h"
int main()
{
Array<char> one = Array<char>();
array_insert(one, 'C');
Array<char> two = one;
return 0;
}
当我尝试将一个数组分配给另一个数组时
Array<char> two = one;
我收到分段错误(核心转储)。我尝试通过实现复制构造函数和复制赋值运算符来解决此问题,但没有帮助。
正如评论中提到的,您没有正确实现复制构造函数和赋值运算符,因为您在使用类成员之前没有初始化它们。 另外,您不应该在 C++ 中使用
malloc()
/realloc()
,而应使用 new[]
和 delete[]
。
此外,您的
array_insert()
也实施错误。 在向数组添加新项目之前,您不会增长数组。 为什么它是一个独立的函数而不是结构体的方法?与array_delete()
相同。
试试这个:
#ifndef ARRAY_H
#define ARRAY_H
#define CAPACITY_SCALE_FACTOR 2
template <typename T>
struct Array
{
private:
T* m_data;
size_t m_size;
size_t m_capacity;
public:
Array()
{
m_size = 0;
m_capacity = 10;
m_data = new T[capacity];
}
~Array()
{
delete[] m_data;
}
T& operator[](size_t index) { return m_data[index]; }
const T& operator[](size_t index) const { return m_data[index]; }
size_t size() const { return m_size; }
size_t capacity() const { return m_capacity; }
Array(const Array &other)
{
m_size = other.m_size;
m_capacity = other.m_size;
m_data = new T[m_capacity];
for (size_t i = 0; i < m_size; ++i)
m_data[i] = other.m_data[i];
}
Array& operator=(const Array& other)
{
if (this != &other)
{
size_t new_capacity = other.m_size;
T *new_data = new T[new_capacity];
for (size_t i = 0; i < other.m_size; ++i)
new_data[i] = other.m_data[i];
delete[] m_data;
m_data = new_data;
m_capacity = new_capacity;
m_size = other.m_size;
}
return *this;
}
void insert(const T &value)
{
if (m_size == m_capacity)
{
size_t new_capacity = m_capacity * CAPACITY_SCALE_FACTOR;
T* new_data = new T[new_capacity];
for(size_t i = 0; i < m_size; ++i)
new_data[i] = m_data[i];
delete[] m_data;
m_data = new_data;
m_capacity = new_capacity;
}
m_data[m_size] = value;
++m_size;
}
void delete(size_t index)
{
if (index >= m_size)
return; // or better, throw an exception, like std::out_of_range...
for (size_t i = index + 1; i < m_size; ++i)
m_data[i-1] = m_data[i];
--m_size;
m_data[m_size] = T();
if (m_size <= (m_capacity / (CAPACITY_SCALE_FACTOR * 2)))
{
size_t new_capacity =
(m_size == 0) ? 1 : m_size * CAPACITY_SCALE_FACTOR;
T *new_data = new T[new_capacity];
for(size_t i = 0; i < m_size; ++i)
new_data[i] = m_data[i];
delete[] m_data;
m_data = new_data;
m_capacity = new_capacity;
}
}
};
#endif
#include "array.h"
int main()
{
Array<char> one;
one.insert('C');
Array<char> two = one;
return 0;
}