-
Operator Overloading Help
I have the following 2 classes:
IntMatrix
Code:
class IntMatrix{
private:
int x[3][4];
};
Matrix
Code:
IntMatrix m, n;
cout << "*** Printing if M == N" << endl;
cout << (m == n) << endl;
cout << "\n*** Printing M" << endl;
m.Print();
m[1][1] = 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?
-
> 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[1][1] = 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();
you could consider overloading operator<< (as a free function) instead.
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[1][2] = 9999 ;
std::cout << m << '\n' ;
}
-
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.
-
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.
-
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[3][5] = 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[6] but only one of them will fit into double tbt[3][2].
-
I have the following two classes:
Code:
class WordMatrix{
private:
char* x[5];
int _ctr;
Matrix
Code:
int Main(){
{WordMatrix a;
a.AddWord("hello");
out << "\n*** Printing A" << endl;
a.Print();
}
WordMatrix a;
a.AddWord("today");
a.AddWord("hello");
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.AddWord("homework");
a.Print();
b.Print();
out << "\n*** b[0] = a[3]" << endl;
b[0] = a[3];
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
*** Adding Homework
today hello world homework
today hello world
*** b[0] = a[3]
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
Also please add any copy constructor, desctructor, or overloaded assignment operator if needed.
-
If you like you could at least explain to me how to add, print, and copy an array of char pointers like char* x[5];.
-
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*.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|