2011-05-20 71 views
1
#include <iostream> 
using namespace std; 

class Array 
{ 
    friend ostream &operator<<(ostream &, const Array &); 
public: 
    Array(int = 5); 
    Array(const Array &); 
    ~Array(); 
    int getSize() const; 
    const Array &operator=(const Array &); 
    // subscript operator for non-const objects returns modifiable lvalue 
    int &operator[](int);    
    // subscript operator for const objects returns rvalue 
    int operator[](int) const; 
private: 
    int size; 
    int *ptr; 
}; 

Array::Array(int arraySize) 
{ 
    size = (arraySize > 0 ? arraySize : 5); // validate arraySize 
    ptr = new int[ size ]; 

    for (int i = 0; i < size; i++) 
     ptr[ i ] = 0; 
} 

// must receive a reference to prevent infinite recursion 
Array::Array(const Array &arrayToCopy) 
    : size(arrayToCopy.size) 
{ 
    ptr = new int[ size ]; // create space for pointer-based array 

    for (int i = 0; i < size; i++) 
     ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object 
} 

Array::~Array() 
{ 
    delete [] ptr; // release pointer-based array space 
} 

int Array::getSize() const 
{ 
    return size; // number of elements in Array 
} 

const Array &Array::operator=(const Array &right) 
{ 
    if (&right != this) // avoid self-assignment 
    { 
     if (size != right.size) 
     { 
     delete [] ptr; // release space 
     size = right.size; // resize this object 
     ptr = new int[ size ]; // create space for array copy 
     } 

     for (int i = 0; i < size; i++) 
     ptr[ i ] = right.ptr[ i ]; // copy array into object 
    } 

    return *this; 
} 

// overloaded subscript operator for non-const Arrays reference return creates a modifiable lvalue 
int &Array::operator[](int subscript) 
{ 
cout << " ***************Inside non-sonstant operator[] function: Lvalue test*********** "; 
    if (subscript < 0 || subscript >= size) 
    { 
     cerr << "\nError: Subscript " << subscript 
     << " out of range" << endl; 
     exit(1); // terminate program; subscript out of range 
    } 

    return ptr[ subscript ]; // reference return 
} 

// overloaded subscript operator for const Arrays const reference return creates an rvalue 
int Array::operator[](int subscript) const 
{ 
cout << " ***************Inside sonstant operator[] function: Rvalue test*********** "; 
    if (subscript < 0 || subscript >= size) 
    { 
     cerr << "\nError: Subscript " << subscript 
     << " out of range" << endl; 
     exit(1); 
    } 

    return ptr[ subscript ]; // returns copy of this element 
} 


// overloaded output operator for class Array 
ostream &operator<<(ostream &output, const Array &a) 
{ 
    int i; 
    // output private ptr-based array 
    for (i = 0; i < a.size; i++) 
    { 
     output << a.ptr[ i ] << " "; 

     if ((i + 1) % 4 == 0) 
     output << endl; 
    } // end for 

    if (i % 4 != 0) 
     output << endl; 

    return output; 
} 

int main() 
{ 
    Array integers1(4); 
    Array integers2; // 5-element Array by default 
    const Array& integers4=integers1; 
    //integers4[3] = 2000; //Error : non-lvalue in assignment 
    integers1 = integers1; //valid 
    integers4 = integers1; //Error : binary '=' : no operator found 
    //which takes a left-hand operand of type 'const Array' (or there is no 
    //acceptable conversion) 
    cout << "\nintegers1[3] is " << integers4[ 3 ]; 

    return 0; 
} 

給出錯誤:錯誤:非左值在分配

1) 在函數'INT主()':

'=':左操作數必須是左值

2) 二進制「=」:沒有操作員發現 ,其採用類型「const的陣列」的左邊的操作數(或不存在 可接受的轉換)

請幫忙。

+0

這是功課嗎? – ildjarn 2011-05-20 23:27:54

+0

順便說一下,你幾個小時前問一個關於const引用的問題[這裏](http://stackoverflow.com/questions/6077332/does-reference-changes-the-state-of-the-referent/6077369#6077369 )。請仔細閱讀所有回覆,因爲其他人經歷了很多麻煩解釋這一點。 – user258808 2011-05-20 23:31:05

+0

他修改了原始變量。 – user258808 2011-05-20 23:34:16

回答

3

不能修改const引用,試試這個:

//Snippet1 
Array& integers4=integers1; 
integers4[3] = 2000; 

爲了澄清有關修改常量引用OP的疑問:

//Snippet2 
//This will not compile as you saw. 
const Array& integers4=integers1; 
integers4[3] = 2000; //errors 

現在,這是什麼XEO在回答這個post一樣。他沒有改變參考,而是改變了原來的變量。

//Snippet2 
//This will compile and work identically to Snippet1. 
const Array& integers4=integers1; 
interger1[3] = 2000; 
+0

這應該修復第二個錯誤 – 2011-05-20 23:28:15

+0

我不得不發佈我的代碼,因爲 - >見[this](http://stackoverflow.com/questions/6077332/does-reference-changes-the-states-of-referent) – munish 2011-05-20 23:31:43

+1

我想還有另一個微妙的錯誤。 @munish編寫的(const)複製賦值操作符不起作用,這可能不是@munish所期望的。我們是否還應該推薦從'const Array&Array :: operator =(const Array&right)'中刪除const,否則編譯器提供的默認值將會生效? – 2011-05-21 01:15:32

2

第一個錯誤 - integers4是一個const Array所以你只能使用constoperator[]返回int,而不是int&。你不能分配給返回的臨時int,你也不應該改變一些常量。
第二個錯誤可能是第一個錯誤的衍生物。

1

論的代碼的特定部件:

Array integers1(4); 
const Array& integers4=integers1; 
//integers4[3] = 2000; //Error : non-lvalue in assignment 

您使用恆定的參考到陣列調用一個成員函數,編譯器將解決調用int Array::operator[](int x) const(的operator[]另一版本需要非const對象)。表達式產生一個右值,你不能指定它。

integers4 = integers1; //Error : binary '=' : no operator found 

再次問題是integers4是常數左值,這意味着它不能(因爲在那裏const)進行修改。

+0

終於有東西進入我厚厚的頭骨 – munish 2011-05-20 23:56:46