Reputation: 4634
#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;
}
Gives errors :
1) In function `int main()':
'=' : left operand must be l-value
2) binary '=' : no operator found which takes a left-hand operand of type 'const Array' (or there is no acceptable conversion)
Please help.
Upvotes: 2
Views: 7586
Reputation: 208323
On the particular pieces of code:
Array integers1( 4 );
const Array& integers4=integers1;
//integers4[3] = 2000; //Error : non-lvalue in assignment
You are using a constant reference to an array to call a member function, and the compiler will resolve the call to int Array::operator[]( int x ) const
(the other version of operator[]
requires a non-const object). The expression yields an rvalue and you cannot assign to it.
integers4 = integers1; //Error : binary '=' : no operator found
Again the issue is that integers4
is a constant lvalue, and that means that it cannot be modified (because of the const
in there).
Upvotes: 1
Reputation: 734
You cannot modify a const reference, Try this:
//Snippet1
Array& integers4=integers1;
integers4[3] = 2000;
To clarify OP's doubt about modifying const references:
//Snippet2
//This will not compile as you saw.
const Array& integers4=integers1;
integers4[3] = 2000; //errors
Now this is what Xeo did in his reply to this post. He did not change the reference, but instead the original variable.
//Snippet2
//This will compile and work identically to Snippet1.
const Array& integers4=integers1;
interger1[3] = 2000;
Upvotes: 3
Reputation: 78914
First error - integers4
is a const Array
so you can only use the const
operator[]
which returns int
rather than int&
. you cannot assign to a returned temporary int
, nor should you be able to change something that is a const.
The second error is probably a derivative of the first.
Upvotes: 2