2011-05-20 70 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