2016-02-13 51 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對和輸入了「你好」和「世界」。 用戶輸入b的大小爲2並輸入「再見」和「世界」。 輸出應該是「Hello World Goodbye World」。

我突出了我認爲問題所在,即+和+ =運算符的重載。我的推理是我創建了一個新數組,用a和b中的值填充它,交換這些值,然後返回所需的連接。

我的推理可能聽起來不太合理,因爲坦率地說,我對如何繼續處理這個問題感到困惑。

+0

爲什麼不'Vector1'還使用複製/交換在'運營商='?它並不是特別安全。 – PaulMcKenzie

+0

爲什麼它不是安全的?我應該用交換替換for循環嗎? – dc90

+0

我應該澄清並說分配運算符是錯誤的。你沒有'刪除'_array'指向的內存(錯誤)。如果你試圖通過發出一個'delete [] _array;'來解決這個問題,那麼它就不是異常安全的,因爲隨後在該函數中調用'new []'可能會拋出一個異常,從而使得你的對象已經摧毀了'_array'。代替所有這些,只需在函數上實現複製/交換。 – 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) {} 

此構造只是構建與num條目的Vector1


鑑於上述情況,要解決的問題:

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的內存,因此您有內存泄漏。

解決這個問題的最簡單方法是使用複製/交換您在使用operator=(Vector1 &&)

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

保羅,我真的很感謝你的幫助。感謝您解釋一切。我還修復了我的複製分配操作員。再次,非常感謝。 – dc90