 DevX Home Today's Headlines   Articles Archive   Tip Bank   Forums

1. Registered User
Join Date
Mar 2009
Posts
24

I have the following 2 classes:

IntMatrix
Code:
```class IntMatrix{
private:
int x;
};```
Matrix
Code:
```IntMatrix m, n;
cout << "*** Printing if M == N" << endl;
cout << (m == n) << endl;
cout << "\n*** Printing M" << endl;
m.Print();
m = 14;
cout << "\n*** Printing M - changed to 14" << endl;
m.Print();
m(2,17);  // replace all 2's with a 17
cout << "\n*** Printing M - changed 2 to 17" << endl;
m.Print();
cout << "\n*** Printing if M == N" << endl;
cout << (m == n) << endl;
IntMatrix p = m+n;
cout << "\n*** Printing P" << endl;
p.Print();
}```
I need to create the public methods in IntMatrix that would make the following display on the screen:

*** Printing if M == N
1

*** Printing M
0 1 2 3
1 2 3 4
2 3 4 5

*** Printing M - changed to 14
0 1 2 3
1 14 3 4
2 3 4 5

*** Printing M - changed 2 to 17
0 1 17 3
1 14 3 4
2 3 4 5

*** Printing if M == N
0

*** Printing P
0 2 19 6
2 16 6 8
19 6 8 10

How do I do this?  Reply With Quote

2. Registered User
Join Date
Dec 2007
Posts
401
> m(2,17); // replace all 2's with a 17
for this, you need to overload the function call operator. this is a bad idea - it is unintuitive, and violates the principle of least surprise. prefer using a named operation like m.replace_all( 2, 17 ) ;

> m = 14;
this is interesting because operator[] needs to be applied twice. you need to create and return a helper object (which encapsulates a single row of the matrix) for the first operator[] on which the second operator[] is applied.

> m.Print();

the rest of it is straightforward - overload operator==, != etc.

Code:
```#include <cstddef>
#include <cassert>
#include <iostream>
#include <iomanip>

class IntMatrix
{
public:
enum { ROWS = 3, COLS = 4 } ;

class helper
{
public :
int& operator[] ( std::size_t col )
{
assert( col < COLS ) ;
return row[col] ;
}

private :
explicit helper( int (&r)[COLS] ) : row(r) {}
int (&row) [COLS] ;

friend class IntMatrix ;
} ;

class const_helper
{
public :
int operator[] ( std::size_t col )
{
assert( col < COLS ) ;
return row[col] ;
}

private :
explicit const_helper( const int (&r)[COLS] ) : row(r) {}
const int (&row) [COLS] ;

friend class IntMatrix ;
} ;

helper operator[] ( std::size_t row )
{
assert( row < ROWS ) ;
return helper( x[row] ) ;
}

const_helper operator[] ( std::size_t row ) const
{
assert( row < ROWS ) ;
return const_helper( x[row] ) ;
}

void operator() ( int old_value, int new_value )
{
for( std::size_t row = 0 ; row < ROWS ; ++row )
for( std::size_t col = 0 ; col < COLS ; ++col )
if( x[row][col] == old_value ) x[row][col] = new_value ;
}

private: int x[ROWS][COLS] ;
};

template< typename OSTREAM >
OSTREAM& operator<< ( OSTREAM& stm, const IntMatrix& m )
{
int w = stm.width() ;

for( std::size_t row = 0 ; row < IntMatrix::ROWS ; ++row )
{
for( std::size_t col = 0 ; col < IntMatrix::COLS ; ++col )
stm << std::setw(12) << m[row][col] ;
stm << '\n' ;
}
stm << '\n' ;

stm.width(w) ;
return stm ;
}

int main()
{
IntMatrix m ;
std::cout << m << '\n' ;
m = 9999 ;
std::cout << m << '\n' ;
}```  Reply With Quote

3. Registered User
Join Date
Mar 2009
Posts
24
I've came up with the following so far:

IntMatrix
Code:
```ofstream outFile("out.txt", ios::app);

IntMatrix::IntMatrix(){
int num = 0;
for(int i=0;i<3;i++)
{
num = i;
for(int j=0;j<4;j++)
{
x[i][j] = num;
num++;
}
}
}

bool IntMatrix::operator == (const IntMatrix & rhs){
bool same = true;
int i, j;

for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++){
if (rhs.x[i][j] == this->x[i][j])
return same;
else same = false;
}
}
return same;
}

void IntMatrix::Print(){
int i, j;

for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
outFile << this->x[i][j] << " ";
outFile << endl;
}
}```
Matrix
ofstream out("out.txt", ios::app);

int main() {
IntMatrix m, n;
out << "*** Printing if M == N" << endl;
out << (m == n) << endl;
out << "\n*** Printing M" << endl;
m.Print();
}

The following prints out:
*** Printing if M == N
1

*** Printing M
0 1 2 3
1 2 3 4
2 3 4 5

I still am having trouble with the [][]. I'm not sure about Vijayan's code in regards to creating and returning a helper object.  Reply With Quote

4. Registered User
Join Date
Dec 2007
Posts
401
e[i][j] is equivalent to ( e[i] ) [j]
one. first apply operator[] on e.
two. then apply operator[] once again on on the object that step one returns.

e[i][j] = 20 ; can be expanded to
some_type temp = e[i] ; // e.operator[] (i) if e is of a user defined type
temp[j] = 20 ;

if you can afford to bypass range checking on the second subscript j, a helper object is not required; you could just return a (reference to) the array that forms row i.
Code:
```#include <cstddef>
#include <cassert>

template< typename T = int, std::size_t ROWS = 3, std::size_t  COLS = 4 >
class Matrix
{
public:

typedef T row_type[COLS] ;
typedef const T const_row_type[COLS] ;

row_type& operator[] ( std::size_t row )
{
assert( row < ROWS ) ;
return x[row] ;
}

const_row_type& operator[] ( std::size_t row ) const
{
assert( row < ROWS ) ;
return x[row] ;
}

// ...

private: T x[ROWS][COLS] ;
};```
Last edited by vijayan; 05-08-2009 at 01:19 AM.  Reply With Quote

5. Senior Member
Join Date
Dec 2003
Posts
3,366
Hopefully this is not too late, but if these are for a real matrix class, let me strongly recommend only using single dimensional storage. For example:

double data[rows*cols];
data[ 3*cols + 5] = 10; //same as (data = 10)

This opens up a lot of crazy matrix routines that create much difficulty in C++ using [][] notation. [][] is ok if everything is a square matrix of the same size, but once you get into reshapes, transposes, non-square multiply, partitioning, etc the [][] style forces you to allocate and copy data around many, many extra times while the single dimensional storage allows you to re-use the memory. consider: you have a 2X3 and transpose it to become a 3X2. They will both fit into double tbt but only one of them will fit into double tbt.  Reply With Quote

6. Registered User
Join Date
Mar 2009
Posts
24
I have the following two classes:

Code:
```class WordMatrix{
private:
char* x;
int _ctr;```
Matrix
Code:
```int Main(){
{WordMatrix a;
out << "\n*** Printing A" << endl;
a.Print();
}
WordMatrix a;
out << "\n*** Printing A" << endl;
a.Print();
a = "world";
out << "\n*** Printing A" << endl;
a.Print();
WordMatrix b = a;
out << "\n*** Printing B" << endl;
b.Print();
out << "\n*** Adding Homework" << endl;
a.Print();
b.Print();
out << "\n*** b = a" << endl;
b = a;
a.Print();
b.Print();
WordMatrix c;
c = b = a;
out << "\n*** Printing A" << endl;
a.Print();
out << "\n*** Printing B" << endl;
b.Print();
out << "\n*** Printing C" << endl;
c.Print();
return 0;```
I need the AddWord(), Print(), operator[], and operator= methods that will print out the following:
*** Printing A
hello

*** Printing A
today hello

*** Printing A
today hello world

*** Printing B
today hello world

today hello world homework
today hello world

*** b = a
today hello world homework
homework hello world

*** Printing A
today hello world homework

*** Printing B
today hello world homework

*** Printing C
today hello world homework  Reply With Quote

7. Registered User
Join Date
Mar 2009
Posts
24
If you like you could at least explain to me how to add, print, and copy an array of char pointers like char* x;.  Reply With Quote

8. Senior Member
Join Date
Dec 2003
Posts
3,366
add is usually, but not always, "concatenate" (spelling?) which, for char arrays, can be done with the C function strcat if your strings always have a null termination. If not, you can do it by hand in a loop.

print: cout and printf both work if your string is properly null terminated. If not print one char at a time instead, in a loop.

copy: strcpy, memcpy, for loop, .... there are many ways to do this. Make sure you understand if you are copying a pointer (probably represents a whole row of data, or one string, depending on how you set it up) or a string, just make extra sure you know what the piece of data you are using actually *is*.  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•