ostream operator

Is it possible to use ostream operator with two const Array Inside? Stable: friend std::ostream &operator<<( std::ostream &, const Array & ); Need: friend std::ostream &operator<<( std::ostream &, const Array & , const Array &)
Reason: Overload two dimensional Array

I'm trying to take two arguments from object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

#define ARRAY_H
#include <iostream>
class Array
{
friend std::ostream &operator<<( std::ostream &, const Array & );
friend std::istream &operator>>( std::istream &, Array & );
public:
explicit Array(int,int ); // default constructor
Array( const Array & ); // copy constructor
~Array(); // destructor
size_t getSize() const; // return size
size_t getColumn() const;


const Array &operator=( const Array & ); // assignment operator
bool operator==( const Array & ) const; // equality operator




// inequality operator; returns opposite of == operator
bool operator!=( const Array &right ) const
{
return ! ( *this == right ); // invokes Array::operator==
} // end function operator!=
// subscript operator for non-const objects returns modifiable lvalue
int &operator[]( int );
// subscript operator for const objects returns rvalue
int operator[]( int ) const;

private:
size_t size; // pointer-based array size
size_t column;


			
int *ptr; // pointer to first element of pointer-based array
int *ptr1;
}; // end class Array

/*

Create a class DoubleSubscriptedArray that has similar features to class Array in Figs. 10.10–
10.11. At construction time, the class should be able to create a DoubleSubscriptedArray of any
number of rows and columns. The class should supply operator() to perform double-subscripting
operations. For example, in a 3-by-5 DoubleSubscriptedArray called chessBoard , the user could
write chessBoard(1, 3) to access the element at row 1 and column 3 . Remember that operator()
can receive any number of arguments. The underlying representation of the DoubleSubscriptedArray
could be a single-subscripted array of integers with rows * columns number of elements. Function
operator() should perform the proper pointer arithmetic to access each element of the underlying
array. There should be two versions of operator() —one that returns int & (so that an element of a

*/





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include "Array.h" // Array class definition
using namespace std;
// default constructor for class Array (default size 10)

Array::Array(int  arraySize, int xColumn )
: size(arraySize), column (xColumn),
 ptr( new int[ size ] ), ptr1( new int[column])

{
cout << "Array Class Constructor 1 On Entry" << endl;

for ( size_t i = 0; i < size; ++i )
ptr[ i ] = 0; // set pointer-based array element

for ( size_t i = 0; i < column; ++i )
ptr1[ i ] = 0; // set pointer-based array element

} // end Array default constructor



// copy constructor for class Array;
// must receive a reference to an Array
//Array::Array( const Array &arrayToCopy )
//: size( arrayToCopy.size ),
//ptr( new int[ size ] )
//{
//cout << "Array Class Constructor 2 On Entry" << endl;
//for ( size_t i = 0; i < size; ++i )
//ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object
//} // end Array copy constructor
// destructor for class Array
Array::~Array()
{
cout << "\nDestructor on Entry, deliting ptr" << endl;
delete [] ptr; // release pointer-based array space
delete [] ptr1; // release pointer-based array space

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


size_t Array::getColumn() const
{
return column; // number of elements in Array
} 




const Array &Array::operator=( const Array &right )
{
if ( &right != this ) // avoid self-assignment
{
// for Arrays of different sizes, deallocate original
// left-side Array, then allocate new left-side Array
if ( size != right.size )
{
delete [] ptr; // release space
size = right.size; // resize this object
ptr = new int[ size ]; // create space for Array copy
} // end inner if
for ( size_t i = 0; i < size; ++i )
ptr[ i ] = right.ptr[ i ]; // copy array into object
} // end outer if
return *this; // enables x = y = z, for example
} // end function operator=
// determine if two Arrays are equal and
// return true, otherwise return false
bool Array::operator==( const Array &right ) const
{
if ( size != right.size )
return false; // arrays of different number of elements
for ( size_t i = 0; i < size; ++i )
if ( ptr[ i ] != right.ptr[ i ] )
return false; // Array contents are not equal
return true; // Arrays are equal
} // end function operator==
// overloaded subscript operator for non-const Arrays;
// reference return creates a modifiable lvalue
int &Array::operator[]( int subscript )
{
// check for subscript out-of-range error
if ( subscript < 0 || subscript >= size )
throw out_of_range( "Subscript out of range" );

return ptr[ subscript ]; // reference return
} // end function operator[]
// overloaded subscript operator for const Arrays
// const reference return creates an rvalue
int Array::operator[]( int subscript ) const
{
// check for subscript out-of-range error
if ( subscript < 0 || subscript >= size )
throw out_of_range( "Subscript out of range" );
return ptr[ subscript ]; // returns copy of this element
} // end function operator[]
// overloaded input operator for class Array;
// inputs values for entire Array
istream &operator>>( istream &input, Array &a )
{
for ( size_t i = 0; i < a.size; ++i )
input >> a.ptr[ i ];
return input; // enables cin >> x >> y;
} // end function
// overloaded output operator for class Array
ostream &operator<<( ostream &output, const Array &a )
{
// output private ptr-based array
for ( size_t i = 0; i < a.size; ++i )
{
output << setw( 12 ) << a.ptr[ i ];
if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output
output << endl;
} // end for
if ( a.size % 4 != 0 ) // end last line of output
output << endl;
return output; // enables cout << x << y;
} // end function operator<< 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include "Array.h"
using namespace std;
void outputArray( const Array & ); // prototype
int main()
{
Array integers1( 7,2 ); // 7-element Array
outputArray( integers1 ); // output Array integers1
outputArray( 3 ); // convert 3 to an Array and output Array’s contents
} // end main
// print Array contents
void outputArray( const Array &arrayToOutput )
{
cout << "The Array received has " << arrayToOutput.getSize()
<< " elements. The contents are:\n" << arrayToOutput << endl;
} // end outputArray 
Last edited on
Why do you want to print two 2D arrays simultaneously?
Overloading must be "compact".
If there is no way to make it easy, i will make two separate functions :)
> Reason: Overload two dimensional Array

Create a two dimensional array class and overload the binary operator for that.
std::ostream& operator<< ( std::ostream& stm, const array_2d& arr )

For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>
#include <iomanip>

struct array_2d
{
    array_2d( std::size_t nrows, std::size_t ncols ) : vec( nrows, std::vector<int>(ncols) ) {}

    auto& operator[] ( std::size_t r ) { return vec.at(r) ; }
    const auto& operator[] ( std::size_t r ) const { return vec.at(r) ; }
    // etc.

    std::vector< std::vector<int> > vec ;

    friend std::ostream& operator<< ( std::ostream& stm, const array_2d& arr )
    {
        for( const auto& row : arr.vec )
        {
            for( int v : row ) stm << std::setw(6) << v ;
            stm << '\n' ;
        }

        return stm ;
    }
};


int main()
{
    const std::size_t nrows = 5 ;
    const std::size_t ncols = 7 ;
    array_2d arr( nrows, ncols ) ;

    for( std::size_t r = 0 ; r < nrows ; ++r )
        for( std::size_t c = 0 ; c < ncols ; ++c )
            arr[r][c] = 10 + r*10 + c ;

    std::cout << arr << '\n' ;
}

http://coliru.stacked-crooked.com/a/1206da35b1b843ff
JLBorges, thanks for reply, but struct syntax is unfamiliar yet for me.
but you're using class! Apart from default access (struct defaults public, class to private), there's no difference between class and struct. So if you can use class, you can use struct.
This is almost hilarious, because the OP does have what looks like a 2D array:
1
2
3
4
5
6
class Array
{
public:
  explicit Array(int,int ); // default constructor
  // ...
};
I wonder where the OP code came from...
impetus wrote:
struct syntax is unfamiliar yet for me.

There are online tutorial resources to learn about structs, and a lot more, Learn C++ is one of the better ones:

https://www.learncpp.com/cpp-tutorial/structs/
Topic archived. No new replies allowed.