Добавление функций в реализацию вектора - PullRequest
0 голосов
/ 02 марта 2011

У меня есть такая реализация вектора, над которой я работал несколько дней, используя примеры из учебника:

#include <iostream>
#include <string>
#include <cassert>
#include <algorithm>
#include <cstring>



// Vector.h

using namespace std;

template <class T>
class Vector
{
public:

   typedef T * iterator;

   Vector();
   Vector(unsigned int size);
   Vector(unsigned int size, const T & initial);
   Vector(const Vector<T> & v);           // copy constructor
   ~Vector();

   unsigned int capacity() const;         // return capacity of vector (in elements)
   unsigned int size() const;             // return the number of elements in the vector
   bool empty() const;

   iterator begin();                      // return an iterator pointing to the first element
   iterator end();                        // return an iterator pointing to one past the last element
   T & front();                           // return a reference to the first element
   T & back();                            // return a reference to the last element
   void push_back(const T & value);       // add a new element
   void pop_back();                       // remove the last element

   void reserve(unsigned int capacity);   // adjust capacity
   void resize(unsigned int size);        // adjust size
   void erase(unsigned int size);     // deletes an element from the vector

   T & operator[](unsigned int index);    // return reference to numbered element
   Vector<T> & operator=(const Vector<T> &);

private:
   unsigned int my_size;
   unsigned int my_capacity;
   T * buffer;
};

template<class T>//
Vector<T>::Vector()
{
    my_capacity = 0;
    my_size = 0;
    buffer = 0;
}

template<class T>
Vector<T>::Vector(const Vector<T> & v)
{
    my_size = v.my_size;
    my_capacity = v.my_capacity;
    buffer = new T[my_size]; 
    for (int i = 0; i < my_size; i++)
        buffer[i] = v.buffer[i];  
}

template<class T>//
Vector<T>::Vector(unsigned int size)
{
    my_capacity = size;
    my_size = size;
    buffer = new T[size];
}

template<class T>//
Vector<T>::Vector(unsigned int size, const T & initial)
{
    my_size = size; //added = size
    my_capacity = size;
    buffer = new T [size];
    for (int i = 0; i < size; i++)
        buffer[i] = initial;
}

template<class T>//
Vector<T> & Vector<T>::operator = (const Vector<T> & v)
{
    delete[ ] buffer;
    my_size = v.my_size;
    my_capacity = v.my_capacity;
    buffer = new T [my_size];
    for (int i = 0; i < my_size; i++)
        buffer[i] = v.buffer[i];
    return *this;
}

template<class T>//
typename Vector<T>::iterator Vector<T>::begin()
{
    return buffer;
}

template<class T>//
typename Vector<T>::iterator Vector<T>::end()
{
    return buffer + size();
}

template<class T>//
T& Vector<T>::Vector<T>::front()
{
    return buffer[0];
}

template<class T>//
T& Vector<T>::Vector<T>::back()
{
    return buffer[size - 1];
}

template<class T>
void Vector<T>::push_back(const T & v)
{
    if (my_size >= my_capacity)
    reserve(my_capacity +5);
    buffer [my_size++] = v;
}

template<class T>//
void Vector<T>::pop_back()
{
    my_size--;
}

template<class T>//
void Vector<T>::reserve(unsigned int capacity)
{
    if(buffer == 0)
    {
        my_size = 0;
        my_capacity = 0;
    }    
    if (capacity <= my_capacity)
    return;
    T * new_buffer = new T [capacity];
    assert(new_buffer);
    copy (buffer, buffer + my_size, new_buffer);
    my_capacity = capacity;
    delete[] buffer;
    buffer = new_buffer;

}

template<class T>//
unsigned int Vector<T>::size()const
{
    return my_size;
}

template<class T>//
void Vector<T>::resize(unsigned int size)
{
    reserve(size);
    my_size = size;
}

template<class T>//
T& Vector<T>::operator[](unsigned int index)
{
    return buffer[index];
}  

template<class T>//
unsigned int Vector<T>::capacity()const
{
    return my_capacity;
}

template<class T>//
Vector<T>::~Vector()
{
    delete[]buffer;
}

template<class T>
void Vector<T>::erase(unsigned int size)
{

}

int main()
{  

   Vector<int> v;

   v.reserve(2);
   assert(v.capacity() == 2);

   Vector<string> v1(2);
   assert(v1.capacity() == 2);
   assert(v1.size() == 2);
   assert(v1[0] == "");
   assert(v1[1] == "");

   v1[0] = "hi";
   assert(v1[0] == "hi");

   Vector<int> v2(2, 7);
   assert(v2[1] == 7);

   Vector<int> v10(v2);
   assert(v10[1] == 7);

   Vector<string> v3(2, "hello");
   assert(v3.size() == 2);
   assert(v3.capacity() == 2);
   assert(v3[0] == "hello");
   assert(v3[1] == "hello");

   v3.resize(1);
   assert(v3.size() == 1);
   assert(v3[0] == "hello");

   Vector<string> v4 = v3;
   assert(v4.size() == 1);
   assert(v4[0] == v3[0]);
   v3[0] = "test";
   assert(v4[0] != v3[0]);  
   assert(v4[0] == "hello");

   v3.pop_back();
   assert(v3.size() == 0);

   Vector<int> v5(7, 9);
   Vector<int>::iterator it = v5.begin();
   while (it != v5.end())
   {
      assert(*it == 9);
      ++it;
   }

   Vector<int> v6;
   v6.push_back(100);
   assert(v6.size() == 1);
   assert(v6[0] == 100);
   v6.push_back(101);
   assert(v6.size() == 2);
   assert(v6[0] == 100);
   v6.push_back(101);

   cout << "SUCCESS\n";
}

Пока все работает довольно хорошо, но я хочу добавить паруфункции, к которым я не могу найти примеры, функция SWAP, которая будет смотреть на два элемента вектора и переключать их значения, и функция ERASE, которая удаляет определенное значение или диапазон значений в векторе.Как начать реализацию двух дополнительных функций?

Ответы [ 4 ]

1 голос
/ 02 марта 2011

Я бы использовал это как упражнение, чтобы увидеть, как работает шаблон проектирования итератора.

vector не имеет подкачки, потому что эта операция может быть выполнена более общим способом с итераторами. Алгоритм std :: swap сделает это за вас, см здесь

Аналогично для стирания вы можете использовать алгоритм std :: transform - http://www.cplusplus.com/reference/algorithm/transform/ - в зависимости от того, что вы имеете в виду под стиранием (вы имеете в виду удаление или перезапись?)

0 голосов
/ 20 апреля 2012

Вам не нужно определять свою собственную функцию подкачки, так как заголовок <iostream> включает в себя функцию std::swap. Но, если вы не хотите использовать std::swap, вы можете определить свою собственную функцию подкачки так:

template<typename _Tp>
void swap(_Tp &a, _Tp &b)
{
    _Tp tempVal = a;
    a = b;
    b = tempVal;
}

Теперь о функции стирания: поскольку вы реализуете вектор с массивом, ваша функция стирания должна:

1) вызвать деструктор элемента, который вы хотите стереть (если он есть)

2) переместить все элементы, которые находятся справа от удаленного элемента на одну позицию влево

3) возвращает итератор произвольного доступа, указывающий на новое местоположение элемента, который следует за последним элементом, стертым при вызове функции, который является концом вектора, если операция стерла последний элемент в последовательности.

4) изменить размер вектора

Предположим, что у вас есть функция стирания, которая стирает один элемент, тогда версия стирания, которая стирает все элементы, выделенные итераторами a, b, будет выглядеть так:

iterator
erase(iterator first, iterator last)
{
while (first != last)
    first = erase(first);
return last;
}
0 голосов
/ 02 марта 2011

Поменять два элемента просто, потому что std :: swap сделает это за вас.

Стирание означает, что вам придется копировать элементы после стертого (ых), чтобы заполнить "дыру".Затем вычтите из размера.

Кстати, у вас есть проблема, когда вы копируете и назначаете из другого вектора.Вы копируете емкость другого вектора, но выделяете размерные элементы в буфере.Это вернется и укусит вас позже!: -)

0 голосов
/ 02 марта 2011

Внедрение свопа должно быть очень простым. Сделайте копию буфера [A], назначьте буфер [B] для буфера [A], назначьте копию для буфера [B].

Стирание также должно быть достаточно прямым. Учитывая диапазон элементов для удаления, сдвиньте элементы после диапазона влево на размер диапазона, затем измените размер вектора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...