2016-02-13 4 views
0
template <typename Object> 
class Vector1 { 
public: 
explicit Vector1(const Object & value = Object()) : size_{0} { 
    array_ = new Object{value}; 
    size_++; 
} 

Vector1(const Vector1 & rhs) : size_{rhs.size_} { //copy constructor 
    array_ = new Object[size_]; 

    for (int i = 0; i < size_; i++) { 
     array_[i] = rhs.array_[i]; 
    } 
} 

Vector1 & operator=(const Vector1 & rhs) { //copy assignment operator 
    array_ = new Object[rhs.size_]; 

    if (this != &rhs) { 
     size_ = rhs.size_; 
     for (int i = 0; i < size_; i++) { 
      array_[i] = rhs.array_[i]; 
     } 
    } 

    return *this; 
} 

Vector1(Vector1 && rhs) : array_{rhs.array_}, size_{rhs.size_} { //move constructor 
    rhs.array_ = nullptr; 
    rhs.size_ = 0; 
} 

Vector1 & operator=(Vector1 && rhs) { //move assignment operator 
    if (this != &rhs) { 
     std::swap(size_, rhs.size_); 
     std::swap(array_, rhs.array_); 
    } 

    return *this; 
} 

void print(ostream & out) const { 
    for (int i = 0; i < size_; i++) { 
     out << array_[i] << " "; 
    } 
} 

void ReadVector1() { 
    int count = 0; 

    cout << "Enter a size: "; 
    cin >> size_; 

    array_ = new Object[size_]; 

    for (int i = 0; i < size_; i++) { 
     cout << "Enter element " << count + 1 << ": "; 
     cin >> array_[i]; 
     count++; 
    } 
} 

size_t Size() const { 
    return size_; 
} 

**Vector1 operator+=(Vector1 & rhs) { 
    size_t combosize = size_ + rhs.size_; 
    Object combo[combosize]; 
    int count = 0, rhscount = 0; 
    for (int i = 0; i < combosize; i++) { 
     if (i % 2 == 0) { 
      combo[i] = array_[count]; 
      count++; 
     } 
     else { 
      combo[i] = rhs.array_[rhscount]; 
      rhscount++; 
     } 
    } 
    std::swap(combosize, rhs.size_); 
    std::swap(combo, rhs.array_); 
    return *this; 
} 
Vector1 operator+(const Vector1 & rhs) const { 
    Vector1 temp(*this); 
    temp += rhs; 
    return temp; 
}** 

~Vector1() { //destructor 
    delete[] array_; 
} 

private: 
    size_t size_; 
    Object *array_; 
}; 

template <typename Object> 
ostream & operator<<(ostream & out, const Vector1<Object> & rhs) { 
    rhs.print(out); 
    return out; 
} 


int main(int argc, char **argv) { 
    Vector1<string> a, b; 

    a.ReadVector1(); //user provides input for Vector1 a 
    cout << a << endl; 

    b.ReadVector1(); //user provides input for Vector1 b 
    cout << b << endl; 

    cout << a + b << endl; //concatenates the two Vector1s 

    Vector1<string> d = a + b; 
    cout << d; 

    return 0; 
} 

Выше мой код (до сих пор). То, что я пытаюсь выполнить, - объединить динамический массив с динамическим массивом b (я не могу использовать векторы или любые STL, это должно быть элементарной имитацией вектора).Конкатенация двух динамических массивов строк?

Пример:

Пользователь вводит размер 2 для входов и «Привет» и «Мир». Пользователь вводит размер 2 для b и вводит «До свидания» и «Мир». Выход должен быть «Hello World Goodbye World».

Я подчеркнул, что проблема заключается в перегрузке операторов + и +. Мое рассуждение состоит в том, что я создаю новый массив, заполняю его значением из a и b, меняю местами значения, а затем возвращаю предполагаемое конкатенацию.

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

+0

Почему не 'Vector1' также использовать копирование/обмен в' 'оператор =? Это не исключение. – PaulMcKenzie

+0

Почему это не безопасно? Должен ли я заменить цикл for на своп? – dc90

+0

Я должен уточнить и сказать, что оператор присваивания ошибочен. Вам не удалось «удалить []] память, на которую указывает __ray] (ошибка). Если вы попытаетесь исправить это, выпуская 'delete [] _array;' вверх, то это не исключение, так как последующий вызов 'new []' в этой функции может вызвать исключение, таким образом испортив ваш объект, так как вы 'разрушен '_array'. Вместо всего этого просто реализуйте функцию copy/swap для функции. – PaulMcKenzie

ответ

0

Есть несколько проблем с вашим кодом относительно operator +=.

Во-первых, operator += должен возвращать ссылку на текущий объект, то есть return *this;. Он не должен возвращать совершенно новый объект Vector1.

Во-вторых, эта линия:

size_t combosize = size_ + rhs.size_; 
Object combo[combosize]; 

не действует ANSI C++, так как массивы должны быть объявлены с выражением времени компиляции для обозначения числа записей. Поскольку combosize - это значение времени выполнения, его нельзя использовать.

Возможно, вы используете компилятор GCC, где имеется расширение длины переменной длины, но опять же это расширение и на самом деле не является частью языка C++.

Кроме того, вам не хватает некоторых конструкторов, которые значительно упростили бы запись operator +=. Конструктор Vector1, что вы не хватает это один:

Vector1::Vector1(size_t num) : array_(new Object[num]), size_(num) {} 

Этот конструктор только создает Vector1 с num записей.


Учитывая вышеизложенное, чтобы исправить проблемы:

Vector1& operator+=(const Vector1 & rhs) 
{ 
    // create a temporary vector 
    Vector1 temp(size_ + rhs.size_); 

    // copy elements to temp array 
    for (int i = 0; i < size_; i++) 
     temp.array_[i] = array_[i]; 

    // copy elements from rhs to temp array 
    int j = 0; 
    for (int i = size_; i < size_ + rhs.size_; i++, j++) 
     temp.array_[i] = rhs.array_[j]; 

    // assign and return 
    *this = temp; 
    return *this; 
} 

Vector1 operator+(const Vector1 & rhs) const 
{ 
    Vector1 temp(*this); 
    temp += rhs; 
    return temp; 
} 

Обратите внимание, что в operator += мы просто создать временный Vector1, заполнить его значениями из * этот и проходящее в Vector1 , и назначить его текущему объекту. Для строки *this = temp; требуется оператор рабочего назначения. См. Следующий раздел ниже.


Другая проблема - ваш Vector1::operator= неверен. Он не освобождает память, выделенную до _array, поэтому у вас есть утечка памяти.

Самый простой способ исправить это, чтобы использовать копию/Swap вы использовали в operator=(Vector1 &&):

Vector1 & operator=(const Vector1 & rhs) 
{ 
    Vector1 temp(rhs); 
    std::swap(size_, temp.size_); 
    std::swap(array_, temp.array_); 
    return *this; 
} 
+0

Пол, я очень ценю вашу помощь. Спасибо, что все объяснили. Я также исправил свой оператор присваивания копий. Еще раз большое спасибо. – dc90

Смежные вопросы