470,575 Members | 2,069 Online

I've been working on creating a Complex class for my own learning purpose
(learn through doing etc.). I'm once again puzzled about something. I can't
figure out how to overload the assignment operator.

Here's what I'm trying to do. I've defined class Complex as

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex operator=( Complex & );
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

The constructor is

Complex::Complex( float a, float b )
: re( a ), im( b ) { }

I have no idea how to write the overload function though. This doesn't work

Complex Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
Help!!!! :-)

Pmb
Jul 22 '05 #1
34 5896
* "Pmb" <so*****@somewhere.com> schriebt:
I have no idea how to write the overload function though. This doesn't work

Complex Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
Help!!!! :-)

Should the "=" operation ever _change_ the value that is on the right
hand side of '='?

No?

In that case, it should be 'const'.

Should you ever be able to write e.g.
a = b = Complex( 1, 2 );

?

Yes?

In that case, the return value should be a reference so that it can
be modified (e.g., in turn invoking '=' on the result).

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
* "Pmb" <so*****@somewhere.com> schriebt:
I have no idea how to write the overload function though. This doesn't work
Complex Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
Help!!!! :-)
Should the "=" operation ever _change_ the value that is on the right
hand side of '='?

No?

In that case, it should be 'const'.

I'm not interested in worrying about const and program integrity at this
point. This code will never be used. This particular program is simply for

Should you ever be able to write e.g.
a = b = Complex( 1, 2 );

?

Yes?

In that case, the return value should be a reference so that it can
be modified (e.g., in turn invoking '=' on the result).

Do you mean something like

Complex &operator=( Complex & );

Complex &Complex::operator=( Complex &z )
{
<??>
return this;
}

I still don't see what to place in the body to do the work. Suppose

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex &operator=( Complex & );
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

It would seem to me that the operator function would be

Complex &Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return this;
}

But this doesn't work.

Pmb
Jul 22 '05 #3
* "Pmb" <so*****@somewhere.com> schriebt:

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
* "Pmb" <so*****@somewhere.com> schriebt:
I have no idea how to write the overload function though. This doesn't work
Complex Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
Help!!!! :-)

Should the "=" operation ever _change_ the value that is on the right
hand side of '='?

No?

In that case, it should be 'const'.

I'm not interested in worrying about const and program integrity at this
point. This code will never be used. This particular program is simply for

'const'.

Should you ever be able to write e.g.
a = b = Complex( 1, 2 );

?

Yes?

In that case, the return value should be a reference so that it can
be modified (e.g., in turn invoking '=' on the result).

Do you mean something like

Complex &operator=( Complex & );

Complex &Complex::operator=( Complex &z )
{
<??>
return this;
}

I still don't see what to place in the body to do the work. Suppose

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex &operator=( Complex & );
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

It would seem to me that the operator function would be

Complex &Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return this;
}

But this doesn't work.

Say rather, it does not _compile_.

First make it compile.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #4
Pmb wrote in news:YJ********************@comcast.com in comp.lang.c++:
I've been working on creating a Complex class for my own learning
purpose (learn through doing etc.). I'm once again puzzled about
something. I can't figure out how to overload the assignment operator.

then *defining* Complex::operator = ( Complex & );
Here's what I'm trying to do. I've defined class Complex as

#include <ostream> /* always try to make your examples compile */
class Complex {
friend ostream &operator<<( ostream &, Complex & );
friend std::ostream &operator<<( std::ostream &, Complex & );

When I compiled your code the above was the only error I found.
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
All of the above *create* a new value, so its appropriate that
they return by value.
Complex operator=( Complex & );
The above dose *not* create a new value, but modifies the
'this' object, logicaly it should return Complex &.

Also it doesn't modify is argument, so you should prefer
Complex const &. As well as being "const correct" this will
allow you to later write code like:

Complex a( 1, 2 ), b( 2, 3 );

a = b.conjugate();

or:

a = a + b;

As the tempraries returned by + and .conjugate() can't be passed
to a function that takes a non-const reference.
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

The constructor is

Complex::Complex( float a, float b )
: re( a ), im( b ) { }

I have no idea how to write the overload function though. This doesn't
work

Complex Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}

What doesn't work about it, with the 'ostream' issue above
fixed it compiles fine for me. Are you sure the error your
seeing isn't coming from elswhere ?
Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #5
> >
I'm not interested in worrying about const and program integrity at this
point. This code will never be used. This particular program is simply for me to learn about writing overload functions for operators.

'const'.

It's worse than that. With certain compilers you will learn illegal C++. If
you then switch to a compiler that enforces const correctness you will have
to relearn C++ that you thought you already knew.

Pmb, its not so hard

Complex operator+( const Complex & ) const;
Complex& operator=( const Complex & );

john
Jul 22 '05 #6

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
* "Pmb" <so*****@somewhere.com> schriebt:

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
* "Pmb" <so*****@somewhere.com> schriebt:
> I have no idea how to write the overload function though. This
doesn't work
>
> Complex Complex::operator=( Complex &z )
> {
> re = z.re;
> im = z.im;
>
> return *this;
> }
>
>
> Help!!!! :-)

Should the "=" operation ever _change_ the value that is on the right
hand side of '='?

No?

In that case, it should be 'const'.

I'm not interested in worrying about const and program integrity at this
point. This code will never be used. This particular program is simply for me to learn about writing overload functions for operators.

'const'.

I didn't say that I refuse to consider const

pmb
Jul 22 '05 #7

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2h************@uni-berlin.de...

I'm not interested in worrying about const and program integrity at this point. This code will never be used. This particular program is simply for me to learn about writing overload functions for operators.
'const'.

It's worse than that. With certain compilers you will learn illegal C++.

If you then switch to a compiler that enforces const correctness you will have to relearn C++ that you thought you already knew.
I think you both read something into what I said that wasn't there. I said
*at this point*. When I learn a new language and try examples I make them as
simple as possible and work my way up. After I got this to compile and got
the logic correct, I was going to go back and place in the const.'s.

Pmb, its not so hard

Complex operator+( const Complex & ) const;
Complex& operator=( const Complex & );

Still doesn't work. However I'm not sure where the error is.

thanks

Pmb
Jul 22 '05 #8

"Rob Williscroft" <rt*@freenet.co.uk> wrote
What doesn't work about it, with the 'ostream' issue above
fixed it compiles fine for me. Are you sure the error your
seeing isn't coming from elswhere ?

There wasn't an "ostream" issue. I simply didn't post the entire code. I
suppose I should have in retrospect. The following is the compile error I
get from the program below

-----------------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
d:\temp\test\example.cpp:
Error E2285 d:\temp\test\example.cpp 130: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 138: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 139: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 140: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 141: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 148: Could not find a match for
'Complex::operator =(Complex)' in function main()
*** 6 errors in Compile ***

Tool completed with exit code 1
------------------

Line 130 is " uConj = u.conjugate();"
Lines 138-141 are

138 "sum = u + v;"
139 "diff = u - v;"
140 "prod = u*v;"
141 "ratio = u/v;"
What am I doing wrong this time?

Thanks

Pmb

_____________________________________________
#include <iostream.h>
#include <math.h>

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex operator=( Complex & );
private:
float re;
float im;
};

ostream &operator<<( ostream &output, Complex &z )
{
float x = z.re, y = z.im;

if ( y == 0 ) // z = a
output << x;
else if ( x == 0 && y > 0 ) // z = i b
output << "i " << y;
else if ( x == 0 && y < 0 ) // z = - i b
output << "- i " << -y;
else if ( x > 0 && y > 0 ) // z = a + i b
output << x << " + i " << z.im;
else if ( x > 0 && y < 0 ) // z = a - i b
output << x << " - i " << -y;
else if ( x < 0 && y < 0 ) // z = -a - i b
output << x << " - i " << -y;
else if ( x < 0 && y > 0 ) // z = -a + i b
output << x << " + i " << y;

return output;
}

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex Complex::operator+( Complex &z )
{
return Complex( re + z.re, im + z.im );
}

Complex Complex::operator-( Complex &z )
{
return Complex( re - z.re, im - z.im );
}

Complex Complex::operator*( Complex &z )
{
// z1 = x1 + i y1, z2 = x2 + i y2
//
// z1*z2 = ( x1 + i y1 )*( x2 + i y2 )
// = ( x1*x2 + i x1*y2 + i x2*y1 - y1*y2
// = ( x1*x2 - y1*y2 ) + i ( x1*y2 + x2*y1 )

float x1 = re, y1 = im, x2 = z.re , y2 = z.im;

return Complex( x1*x2 - y1*y2, x1*y2 + x2*y1 );
}

Complex Complex::operator/( Complex &z )
{
// z1 = x1 + i y1, z2 = x2 + i y2
//
// z1 z1 z2* z1*z2 z1*z2
// -- = -- -- = ------ = -------------
// z2 z2 z2* |z2|^2 x1*x1 + y1*y1
//
// z1*z2 = ( x1*x2 - y1*y2 ) + i ( x1*y2 + x2*y1 )
//
// z1 x1*x2 - y1*y2 x1*y2 + x2*y1
// -- = ----------------- + i -------------
// z2 x1*x1 + y1*y1 x1*x1 + y1*y1
//
// a = x1*x2 - y1*y2, b = x1*y2 + x2*y1, c = x1*x1 + y1*y1
//
// z1 a b
// -- = -- + i -- = x + i y
// z2 c c
//
// x = a/c, y = b/c
//
float x1 = re, y1 = im, x2 = z.re , y2 = z.im;
float a, b, c, x, y;

a = x1*x2 - y1*y2;
b = x1*y2 + x2*y1;
c = x1*x1 + y1*y1;
x = a/c;
y = b/c;

return Complex( x, y );
}

Complex Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
Complex Complex::conjugate()
{
return Complex( re, -im);
}

float Complex::magnitude()
{
return sqrt( re*re + im*im );
}

int main()
{
Complex u( 1, 5 ), v( 2, 2 ), w( 1, 1 );
Complex uConj, sum, prod, diff, ratio;
float r;

uConj = u.conjugate();
r = u.magnitude();

cout << "\nu = " << u << endl;
cout << "\nv = " << v << endl;
cout << "\nu* = " << uConj << endl;
cout << "\n|u| = " << r << endl;

sum = u + v;
diff = u - v;
prod = u*v;
ratio = u/v;

cout << "\nu + v = " << sum << endl;
cout << "\nu - v = " << diff << endl;
cout << "\nu*v = " << prod << endl;
cout << "\nu/v = " << ratio << endl;

sum = u + v + w;
cout << "\nu + v + w = " << sum << endl;

return 0;
}
_____________________________________________
Jul 22 '05 #9

"Pmb" <so*****@somewhere.com> wrote in message
news:Xs********************@comcast.com...

"Rob Williscroft" <rt*@freenet.co.uk> wrote
What doesn't work about it, with the 'ostream' issue above
fixed it compiles fine for me. Are you sure the error your
seeing isn't coming from elswhere ?

There wasn't an "ostream" issue. I simply didn't post the entire code. I
suppose I should have in retrospect. The following is the compile error I
get from the program below

-----------------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
d:\temp\test\example.cpp:
Error E2285 d:\temp\test\example.cpp 130: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 138: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 139: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 140: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 141: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 148: Could not find a match for
'Complex::operator =(Complex)' in function main()
*** 6 errors in Compile ***

Tool completed with exit code 1
------------------

Line 130 is " uConj = u.conjugate();"
Lines 138-141 are

138 "sum = u + v;"
139 "diff = u - v;"
140 "prod = u*v;"
141 "ratio = u/v;"
What am I doing wrong this time?

Forgetting const, put the const in and it will compile.

Complex& operator=(const Complex & );

What you are failing to realise is that you cannot bind a temporary to a
non-const reference.

sum = u + v;

u + v returns a temporary, you have declared your operator= with a non-const
reference. Therefore you cannot use u + v on the right hand side of a
operator=.

john
Jul 22 '05 #10

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2h************@uni-berlin.de...

"Pmb" <so*****@somewhere.com> wrote in message
news:Xs********************@comcast.com...

"Rob Williscroft" <rt*@freenet.co.uk> wrote
What doesn't work about it, with the 'ostream' issue above
fixed it compiles fine for me. Are you sure the error your
seeing isn't coming from elswhere ?
There wasn't an "ostream" issue. I simply didn't post the entire code. I
suppose I should have in retrospect. The following is the compile error I get from the program below

-----------------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
d:\temp\test\example.cpp:
Error E2285 d:\temp\test\example.cpp 130: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 138: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 139: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 140: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 141: Could not find a match for
'Complex::operator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 148: Could not find a match for
'Complex::operator =(Complex)' in function main()
*** 6 errors in Compile ***

Tool completed with exit code 1
------------------

Line 130 is " uConj = u.conjugate();"
Lines 138-141 are

138 "sum = u + v;"
139 "diff = u - v;"
140 "prod = u*v;"
141 "ratio = u/v;"
What am I doing wrong this time?

Forgetting const, put the const in and it will compile.

Complex& operator=(const Complex & );

What you are failing to realise is that you cannot bind a temporary to a
non-const reference.

I see no reason for that to be true.
sum = u + v;

u + v returns a temporary, you have declared your operator= with a non-const reference. Therefore you cannot use u + v on the right hand side of a
operator=.

I disagree. I simplified the code I'm working on to the bare bones. It now

_______________________________________
#include <iostream.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex &operator=( Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex& Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
int main()
{
Complex z1( 1, 5 ), z2( 0, 0 );
float x, y;

x = z2.getRe();
y = z2.getIm();

cout << "Components before 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

z2 = z1;

x = z2.getRe();
y = z2.getIm();

cout << "\nComponents after 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

return 0;
}
_______________________________________

This program works just fine. The output is

------------
Components before 'operator=' call: (x,y) = (0,0)

Components after 'operator=' call: (x,y) = (1,5)
------------

That is exactly what I want it to do. Had I wanted to use this code further
then perhaps I'd used const's. Not while I'm in a learning mode. When
learning one seeks to understand when something is required and when it is
not required and how it affects the logic etc. Perhaps everyone disagrees
with the way I chose to learn. But that is the way I choose to learn

Pmb
Jul 22 '05 #11
> >
Forgetting const, put the const in and it will compile.

Complex& operator=(const Complex & );

What you are failing to realise is that you cannot bind a temporary to a
non-const reference.
I see no reason for that to be true.

You might not see a reason, other people don't see the reason, its somewhat
controversial, but its in the C++ standard in black and white. However some
compilers do not enforce that rule.

sum = u + v;

u + v returns a temporary, you have declared your operator= with a

non-const
reference. Therefore you cannot use u + v on the right hand side of a
operator=.

I disagree. I simplified the code I'm working on to the bare bones. It

Fine but you've changed the program to avoid the problem I described. You no
longer have a temporary on the rhs of an assignment.

_______________________________________
#include <iostream.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex &operator=( Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex& Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
int main()
{
Complex z1( 1, 5 ), z2( 0, 0 );
float x, y;

x = z2.getRe();
y = z2.getIm();

cout << "Components before 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

z2 = z1;

x = z2.getRe();
y = z2.getIm();

cout << "\nComponents after 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

return 0;
}
_______________________________________

This program works just fine. The output is

------------
Components before 'operator=' call: (x,y) = (0,0)

Components after 'operator=' call: (x,y) = (1,5)
------------

That is exactly what I want it to do. Had I wanted to use this code further then perhaps I'd used const's. Not while I'm in a learning mode. When
learning one seeks to understand when something is required and when it is
not required and how it affects the logic etc. Perhaps everyone disagrees
with the way I chose to learn. But that is the way I choose to learn

I was just answering the question you asked, 'What have I done wrong this
time?' I pointed out a way (the only way) to make your program compile, you
chose to write a different program instead.

john
Jul 22 '05 #12

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2h************@uni-berlin.de...

Forgetting const, put the const in and it will compile.

Complex& operator=(const Complex & );

What you are failing to realise is that you cannot bind a temporary to a non-const reference.
I see no reason for that to be true.

You might not see a reason, other people don't see the reason, its

somewhat controversial, but its in the C++ standard in black and white. However some compilers do not enforce that rule.

sum = u + v;

u + v returns a temporary, you have declared your operator= with a non-const
reference. Therefore you cannot use u + v on the right hand side of a
operator=.

I disagree. I simplified the code I'm working on to the bare bones. It

now

Fine but you've changed the program to avoid the problem I described. You

no longer have a temporary on the rhs of an assignment.

_______________________________________
#include <iostream.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex &operator=( Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex& Complex::operator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}
int main()
{
Complex z1( 1, 5 ), z2( 0, 0 );
float x, y;

x = z2.getRe();
y = z2.getIm();

cout << "Components before 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

z2 = z1;

x = z2.getRe();
y = z2.getIm();

cout << "\nComponents after 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

return 0;
}
_______________________________________

This program works just fine. The output is

------------
Components before 'operator=' call: (x,y) = (0,0)

Components after 'operator=' call: (x,y) = (1,5)
------------

That is exactly what I want it to do. Had I wanted to use this code further
then perhaps I'd used const's. Not while I'm in a learning mode. When
learning one seeks to understand when something is required and when it is not required and how it affects the logic etc. Perhaps everyone disagrees with the way I chose to learn. But that is the way I choose to learn

I was just answering the question you asked, 'What have I done wrong this
time?' I pointed out a way (the only way) to make your program compile,

you chose to write a different program instead.

I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it
is) then I would have missed this point had I put them in solely for the
purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb
Jul 22 '05 #13
>
I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it
is) then I would have missed this point had I put them in solely for the
purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb

In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has never
been true in C++.

john
Jul 22 '05 #14

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2h************@uni-berlin.de...

I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it is) then I would have missed this point had I put them in solely for the
purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb

In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has

never been true in C++.

What does the C++ standard say on this issue?

Pmb
Jul 22 '05 #15

----- Original Message -----
From: "John Harrison" <jo*************@hotmail.com>
Newsgroups: comp.lang.c++
Sent: Saturday, May 29, 2004 7:50 AM

I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it is) then I would have missed this point had I put them in solely for the
purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb

In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has

never been true in C++.
While I now understand that I *must* put const in I still don't understand
*why* I must do that? You wrote
What you are failing to realise is that you cannot bind a temporary to a non-const reference.

What does "bind a temporary" mean?
sum = u + v;

u + v returns a temporary, ...
Please clarify. What do you mean by "returns a temporary"? I assume that
you're referring to the return value of

Complex Complex::operator+( Complex &z )

Since this is a temporary and since this is what goes into the input of

Complex& Complex::operator=( const Complex &z )

Then shouldn't the input be temporary?
...you have declared your operator= with a non-const
reference.

Doesn't "non-constant" mean "temporary"?

Thanks

Pmb

ps - Sorry. I accidently sent this to your e-mail too
Jul 22 '05 #16
Pmb posted:

While I now understand that I *must* put const in I still don't
understand *why* I must do that?

int a = 6;
const int b = 5;
const int c = 4;
a = b;
Self explanatory I hope.

What you are failing to realise is that you cannot bind a temporary to
a non-const reference.

What does "bind a temporary" mean?
sum = u + v;

u + v returns a temporary, ...

Please clarify. What do you mean by "returns a temporary"?

unsigned int GiveNumber(void)
{
return 27;
}

int main(void)
{
int& given_number = GiveNumber();
given_number = 27; //Guess what happens here...

//The object returned from GiveNumber no longer exists, I have
//a hanging pointer, in the form of a reference. And I just accessed
//"unallocated" memory, memory that ain't mine. BOLD!
}
Jul 22 '05 #17
Hi Pmb, ( and all you C++ guys too ) [ Posted & e-mailed ]

You showed, " sum = u + v; ".

And in your e-mail to me you showed:
cin >> "Enter z = x + i y: " >> z;

I'd be nice if one could say:
cin >>
"Enter z, ( in the form: Real + Imaginary ): " >> z;

Then the user could simply type in something like:
5 + 6

But you can't overload the + symbol like that,
because it reacts to the type of the operands,
which, in this case, are not even reals,
much less complex. ( They are integers )

Could that be solved by
using something other than the + symbol ?

Correct me if I'm wrong here C++ guys,
but I think the only solution is
to use string input like this:

float Real; String A_String_Operator; float Imaginary;
cin >>
"Enter z,"
" ( in the form: Real + Imaginary, "
" spaces required ): " >>
Real >> A_String_Operator >> Imaginary;

Then the user could simply type in something like:
5 + 6
Jul 22 '05 #18
"Pmb" <so*****@somewhere.com> wrote in message
news:dI********************@comcast.com
----- Original Message -----
From: "John Harrison" <jo*************@hotmail.com>

While I now understand that I *must* put const in I still don't
understand *why* I must do that? You wrote
What you are failing to realise is that you cannot bind a temporary
to a non-const reference.
What does "bind a temporary" mean?

A reference refers to an object. A reference is "bound to a temporary" when
it is made to refer to a temporary. The binding takes place in this instance
when the temporary is passed as the operator argument.
sum = u + v;

u + v returns a temporary, ...

Please clarify. What do you mean by "returns a temporary"? I assume
that you're referring to the return value of

Complex Complex::operator+( Complex &z )

Correct.
Since this is a temporary and since this is what goes into the input
of

Complex& Complex::operator=( const Complex &z )

Then shouldn't the input be temporary?
Yes, the input is a temporary. But the reference is a const reference. You
are allowed to bind temporaries to const references, but not to non-const
references.
Doesn't "non-constant" mean "temporary"?

No. const and non-const has to do with the right to modify an object. When
you declare an operator with

Complex& Complex::operator=(Complex &z );

the operator has the right to modify whatever is passed in as its argument.
Thus the assignment in

z = u;

would allow u to be modified by the assignment operator. By contrast, a
declaration of

Complex& Complex::operator=( const Complex &z );

means that the assignment operator is not allowed to modify its argument (u
in the above example).

Why is only the second version allowed when the argument is a temporary?
This is to prevent programmers from making a particular type of error. If a
function or operator modifies its argument, then that usually means that the
programmer wishes to change the object in the scope from which the function
or operator has been called, as in the following example:

void DoubleValue(int &n)
{
n *=2;
}

int main()
{
int m = 2;
DoubleValue(m);
// m will now be 4
}

Now if the argument passed to a function is a temporary, then the function's
action will change the value of the temporary, but the temporary will cease
to exist as soon as the function returns. Thus the function will not have an
effect in the scope from which it is called. This may be an unpleasant
surprise to the programmer, so the language prevents the passing of
temporaries to functions and operators with non-const reference parameters
in order to eliminate the possibility of this unpleasant surprise. The risk
of this surprise is greater than you might think because temporaries get
generated in more cases than you might think.
--
John Carson

Jul 22 '05 #19

"Pmb" <so*****@somewhere.com> wrote in message
news:dI********************@comcast.com...

----- Original Message -----
From: "John Harrison" <jo*************@hotmail.com>
Newsgroups: comp.lang.c++
Sent: Saturday, May 29, 2004 7:50 AM

I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it is) then I would have missed this point had I put them in solely for the purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb

In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has

never
been true in C++.

While I now understand that I *must* put const in I still don't understand
*why* I must do that? You wrote
What you are failing to realise is that you cannot bind a temporary to a

non-const reference.

What does "bind a temporary" mean?
sum = u + v;

u + v returns a temporary, ...

Please clarify. What do you mean by "returns a temporary"? I assume that
you're referring to the return value of

Complex Complex::operator+( Complex &z )

Since this is a temporary and since this is what goes into the input of

Complex& Complex::operator=( const Complex &z )

Then shouldn't the input be temporary?
...you have declared your operator= with a non-const
reference.

Doesn't "non-constant" mean "temporary"?

Thanks

Pmb

A temporary is an unnamed object. 'u + v' returns a Complex object, but that
object has no name, so it's a temporary (the compiler creates it when the
functions returns and destroys it when it been used, hence its called a
temporary). Any function or operator that returns an object returns a
temporary. There are various other ways to create temporaries

class X
{
public:
X(int x);
};

void f(const X& x);

f(1);

There's a constructor for X that takes an int, so when you try to call f
using an int, the compiler creates a temporary X from the int and uses that
to call f.

You can also create temporaries explicitly

Complex z = Complex(1.0, 2.0) + Complex(3.0, 4.0);

The objects created by Complex(1.0, 2.0) and Complex(3.0, 4.0) have no name,
they are temporaries.

When a reference is initialised its usually referred to as binding a
reference.

int x;
int& y = x; // y is bound to x

Now the crunch, a temporary cannot be bound to a non-const reference.
Suppose you have written

class Complex
{
public:
Complex operator+(Complex& rhs);

Now this is illegal

Complex z = Complex(1.0, 2.0) + Complex(3.0, 4.0);

The right hand side of your operator+ is a temporary but you operator+ has
been written with a non-const reference, so the above should not compile.
Similarly

Complex f();

Complex z = Complex(1.0, 2.0) + f();

Again the right hand side is a temporary.

Why does C++ have this rule? That's a good question, Bjarne Stroustrup says
that it leads to code that is too confusing, he has in mind code like this

void trim_whitespace(string& s); // removes whitespace from s

trim_whitespace(" abc ");

Without the 'can't bind a temporary to a non-const reference' rule the
compiler would create a temporary string from " abc ", that would be passed
to trim_whitespace, which would faithfully remove the whitespace, but when
the function returns the temporary (with its whitespace removed) would be
destroyed. The original string literal " abc " would be completely
untouched.

With the rule the above will not compile, which it what you would want.

As I said this isn't uncontroversial, but it is the way C++ is. If you want
to consult the standard 8.5.3 para 5

john
Jul 22 '05 #20
Jeff Relf wrote:
Hi Pmb, ( and all you C++ guys too ) [ Posted & e-mailed ]

You showed, " sum = u + v; ".

And in your e-mail to me you showed:
cin >> "Enter z = x + i y: " >> z;
Whoever wrote that is leading you astray. 'cin' is not some kind of magic
prompt system. The string literal will turn to a constant char pointer,
which won't compile.

Try

cout << "Enter z = x + i y: ";
std::string zee;
std::getline(cin, zee);

That interprets linefeeds as turnaround characters. But then you must parse
zee and get the integer out of it.
I'd be nice if one could say:
cin >>
"Enter z, ( in the form: Real + Imaginary ): " >> z;

Then the user could simply type in something like:
5 + 6

But you can't overload the + symbol like that,
because it reacts to the type of the operands,
which, in this case, are not even reals,
much less complex. ( They are integers )
The user can't type + unless you parse it. If you do, you get to decree what
it does.
Could that be solved by
using something other than the + symbol ?

Correct me if I'm wrong here C++ guys,
but I think the only solution is
to use string input like this:

float Real; String A_String_Operator; float Imaginary;
cin >>
"Enter z,"
" ( in the form: Real + Imaginary, "
" spaces required ): " >>
Real >> A_String_Operator >> Imaginary;

Are you compiling and testing these things before asking? Always edit,
compile, and test in tiny little cycles, adding one ability at a time.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #21
Hi Phlip,

Is it possible to use any symbol I want
to define an operator, e.g.:
Complex & Complex::operator $( Complex const & z ) Complex C = 5$ 1;

float Real; String A_String_Operator; float Imaginary;
cout << "Enter z,"
" ( in the form: Real + Imaginary, "
" spaces required ): ";
cin >> Real >> A_String_Operator >> Imaginary;

I don't have any console applications to test this in,
so I didn't bother to compile it,
And I never use cout or cin myself.
Jul 22 '05 #22
Hi JKop,

Here's how I'd explain what a " temporary " is:

int & In_A_Stack ( ) {
// 1 here is a temporary, because it's in a stack.
return 1; }

int main ( ) {
// This puts 6 in a stack somewhere,
// but it will soon be overwritten,
// as the stack will soon be popped.
In_A_Stack () = 6; }
Jul 22 '05 #23
Hi John Harrison,

So, Given:
int Same_Thing_As_Reference ;
int & Reference = Same_Thing_As_Reference ;

The = symbol " binds "
Same_Thing_As_Reference to Reference.

Hence,
Whatever happens to Reference
also happens to Same_Thing_As_Reference,
because they are the same thing.
Jul 22 '05 #24
Jeff Relf wrote:
Is it possible to use any symbol I want
to define an operator, e.g.:
Complex & Complex::operator $( Complex const & z ) Complex C = 5$ 1;
No. Your friendly neighborhood C++ tutorial might list the ones you can use.
They include |=, comma, and [], but not # or $or {}. The above code attempts to create "syntactic sugar". If Complex needs two arguments to construct, then it needs a constructor that takes two arguments. Sorry about the bad syntax in my last post, I meant: float Real; String A_String_Operator; float Imaginary; cout << "Enter z," " ( in the form: Real + Imaginary, " " spaces required ): "; cin >> Real >> A_String_Operator >> Imaginary; I don't have any console applications to test this in, so I didn't bother to compile it, And I never use cout or cin myself. I can't repair car engines, and I don't have a car, but I have a spark plug. What should I set its gap to? Your questions must come from your direct experience attempting to write these programs. Else the group will mire in endless distractions, such as the difference between String and std::string. Regardless of how you collect user input, here's the Miniature Language Pattern for C++: typedef std::map<string, string> params_t; typedef bool (*case_t)(params_t &); std::map<string, case_t> testCommands; bool quotient(params_t & testCase) { double num (strtod(testCase["numerator" ].c_str(), NULL)); double den (strtod(testCase["denominator"].c_str(), NULL)); double quo (strtod(testCase["quotient()" ].c_str(), NULL)); return num / den == quo; } bool sum(params_t & testCase) { double num (strtod(testCase["augend"].c_str(), NULL)); double den (strtod(testCase["addend"].c_str(), NULL)); double quo (strtod(testCase["sum()" ].c_str(), NULL)); return num + den == quo; } bool Product(params_t & testCase) { double num (strtod(testCase["Input1"].c_str(), NULL)); double den (strtod(testCase["Input2"].c_str(), NULL)); double quo (strtod(testCase["Product()" ].c_str(), NULL)); return num * den == quo; } void registerListOfActions() { testCommands["quotient()"] = quotient; testCommands["sum()" ] = sum; testCommands["Product()" ] = Product; } Now when you call this... case_t case_ = testCommands[key]; if (case_) return case_(testCase); ....if key is "Product()" you call the Product() function, and if key is "sum()" you call sum(), etc. The arguments to the function go in as a map of strings in testCase: testCase["Input1"] = 5; testCase["Input2"] = 2; testCase["Product()"] = 10; -- Phlip http://industrialxp.org/community/bi...UserInterfaces Jul 22 '05 #25 Hi Phlip, You mentioned, " If Complex needs two arguments to construct, then it needs a constructor that takes two arguments. " So then, No symbol can be used to create a complex number from integers. Hence, One must do something like: Complex( 3, 2 ); You showed: typedef std::map<string, string> params_t; You lost me at: map < string, string > Oh well, no big deal. Jul 22 '05 #26 Jeff Relf wrote: You mentioned, " If Complex needs two arguments to construct, then it needs a constructor that takes two arguments. " Your editor probably supports "reply ticks". They make these replies easier to write and read. So then, No symbol can be used to create a complex number from integers. Hence, One must do something like: Complex( 3, 2 ); No, I said$ could not, and that such a symbol would be syntactic sugar.

But if you like to overloading operator!=, that would break much code that
uses != with two integer arguments, so overloading an operator would indeed
be difficult.
You showed:
typedef std::map<string, string> params_t;

You lost me at: map < string, string >

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #27
"Pmb" <so*****@somewhere.com> schreef in bericht
news:mM********************@comcast.com...

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
* "Pmb" <so*****@somewhere.com> schriebt:

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
> * "Pmb" <so*****@somewhere.com> schriebt:
> > I have no idea how to write the overload function though. This doesn't work
> >
> > Complex Complex::operator=( Complex &z )
> > {
> > re = z.re;
> > im = z.im;
> >
> > return *this;
> > }
> >
> >
> > Help!!!! :-)
>
> Should the "=" operation ever _change_ the value that is on the right > hand side of '='?
>
> No?
>
> In that case, it should be 'const'.

I'm not interested in worrying about const and program integrity at this point. This code will never be used. This particular program is simply for me to learn about writing overload functions for operators.

'const'.

I didn't say that I refuse to consider const

Constness is a very important part of overloading. You cannot learn operator
Jul 22 '05 #28

"Wouter Lievens" <li***********@snotmail.com> wrote in message
news:40**********************@news.skynet.be...
"Pmb" <so*****@somewhere.com> schreef in bericht
news:mM********************@comcast.com...

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
* "Pmb" <so*****@somewhere.com> schriebt:
>
> "Alf P. Steinbach" <al***@start.no> wrote in message
> news:40****************@news.individual.net...
> > * "Pmb" <so*****@somewhere.com> schriebt:
> > > I have no idea how to write the overload function though. This doesn't
> work
> > >
> > > Complex Complex::operator=( Complex &z )
> > > {
> > > re = z.re;
> > > im = z.im;
> > >
> > > return *this;
> > > }
> > >
> > >
> > > Help!!!! :-)
> >
> > Should the "=" operation ever _change_ the value that is on the right > > hand side of '='?
> >
> > No?
> >
> > In that case, it should be 'const'.
>
> I'm not interested in worrying about const and program integrity at this > point. This code will never be used. This particular program is
simply for

'const'.

I didn't say that I refuse to consider const

I've explained this a dozen times here. Where did you get the impression
that I wasn't going to use it? And I still don't see that I have to use it

My goal is not to write good code right now. As I've said many times in this
thread - My sole goal at this point is to learn C++. Nothing more and
nothing less. I've chosen to omit the const in certain places to understand
where they absolutely must be used, where one does not have to use them and
why, as well as what the compiler's do when I do it wrong. That way in the
future if I see a compile error I will know what caused it.

e.g. the program below works just fine. The impression that I've gotten from
all these "You have to do that or its wrong" comments is that leaving it out
where I have below will give a compile error.
____________________________________________
#include <iostream.h>
#include <math.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & ) ;
const Complex &operator=( const Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex Complex::operator+( Complex &z )
{
return Complex( re + z.re, im + z.im );
}

const Complex& Complex::operator=( const Complex &z )
{
re = z.re;
im = z.im;
return *this;
}

int main()
{
Complex z1, z2, a( 1, 5 ), b( 2, 2 ), c( 7, 3 );
float x, y;

z1 = Complex( 7, 5 );
x = z1.getRe();
y = z1.getIm();

cout << "z = ( " << x << ", " << y << " )" << endl;

z2 = a + b + c;
x = z2.getRe();
y = z2.getIm();
cout << "z = ( " << x << ", " << y << " )" << endl;

return 0;
}
____________________________________________

Output
------------------
z = ( 7, 5 )
z = ( 10, 10 )
------------------

Please explain why this result obtained even though I didn't use "const" as
you indicatred absolutely must be done.

Please explain what you mean by "You simply HAVE to use it." when the
program works as I expected it to.

Pmb
Jul 22 '05 #29
Jeff Relf wrote:

Hi Phlip,

You noted,
" But if you [ overloaded the ] operator !=,
that would break much code
that uses != with two integer arguments,

That must be the understatement of the year.

As for my quoting style,
That's just the way that I prefer it.
I don't like the usual quoting methods.

Then prepare to not getting answers.
It is you who wants help, not us.

--
Karl Heinz Buchegger
Jul 22 '05 #30
Pmb wrote:

"Wouter Lievens" <li***********@snotmail.com> wrote in message
news:40**********************@news.skynet.be...
"Pmb" <so*****@somewhere.com> schreef in bericht
news:mM********************@comcast.com...

"Alf P. Steinbach" <al***@start.no> wrote in message
news:40****************@news.individual.net...
> * "Pmb" <so*****@somewhere.com> schriebt:
> >
> > "Alf P. Steinbach" <al***@start.no> wrote in message
> > news:40****************@news.individual.net...
> > > * "Pmb" <so*****@somewhere.com> schriebt:
> > > > I have no idea how to write the overload function though. This
doesn't
> > work
> > > >
> > > > Complex Complex::operator=( Complex &z )
> > > > {
> > > > re = z.re;
> > > > im = z.im;
> > > >
> > > > return *this;
> > > > }
> > > >
> > > >
> > > > Help!!!! :-)
> > >
> > > Should the "=" operation ever _change_ the value that is on the right
> > > hand side of '='?
> > >
> > > No?
> > >
> > > In that case, it should be 'const'.
> >
> > I'm not interested in worrying about const and program integrity at

this
> > point. This code will never be used. This particular program is simply for
>
> 'const'.

I didn't say that I refuse to consider const

operator

I've explained this a dozen times here. Where did you get the impression
that I wasn't going to use it? And I still don't see that I have to use it

My goal is not to write good code right now. As I've said many times in this
thread - My sole goal at this point is to learn C++. Nothing more and
nothing less. I've chosen to omit the const in certain places to understand
where they absolutely must be used, where one does not have to use them and
why, as well as what the compiler's do when I do it wrong. That way in the
future if I see a compile error I will know what caused it.

e.g. the program below works just fine. The impression that I've gotten from
all these "You have to do that or its wrong" comments is that leaving it out
where I have below will give a compile error.
____________________________________________
#include <iostream.h>
#include <math.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & ) ;
const Complex &operator=( const Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex Complex::operator+( Complex &z )
{
return Complex( re + z.re, im + z.im );
}

const Complex& Complex::operator=( const Complex &z )
{
re = z.re;
im = z.im;
return *this;
}

int main()
{
Complex z1, z2, a( 1, 5 ), b( 2, 2 ), c( 7, 3 );
float x, y;

z1 = Complex( 7, 5 );
x = z1.getRe();
y = z1.getIm();

cout << "z = ( " << x << ", " << y << " )" << endl;

z2 = a + b + c;
x = z2.getRe();
y = z2.getIm();
cout << "z = ( " << x << ", " << y << " )" << endl;

return 0;
}
____________________________________________

Output
------------------
z = ( 7, 5 )
z = ( 10, 10 )
------------------

Please explain why this result obtained even though I didn't use "const" as
you indicatred absolutely must be done.

But you did.
opertor= takes a const reference, as it it should

Please explain what you mean by "You simply HAVE to use it." when the
program works as I expected it to.

Because you avoided the cases where it makes a difference.

Why do I have to drive on the right side on the road. I have
driven 100-eds of miles without accident on the wrong side.
Well. yes I drove at night when no one else was around, but still:
--
Karl Heinz Buchegger
Jul 22 '05 #31
On Sat, 29 May 2004 05:57:12 -0700, Jeff Relf <Me@Privacy.NET> wrote:
Hi Pmb, ( and all you C++ guys too ) [ Posted & e-mailed ]

You showed, " sum = u + v; ".

And in your e-mail to me you showed:
cin >> "Enter z = x + i y: " >> z;

I'd be nice if one could say:
cin >>
"Enter z, ( in the form: Real + Imaginary ): " >> z;

Then the user could simply type in something like:
5 + 6

But you can't overload the + symbol like that,
because it reacts to the type of the operands,
which, in this case, are not even reals,
much less complex. ( They are integers )
is operator>>. The input string itself can use anything you like. 5 +
6i (or use the engineering "j"), or whatever. You seem to be confusing
language abilities with the abilities of your program.
Could that be solved by
using something other than the + symbol ?

Correct me if I'm wrong here C++ guys,
but I think the only solution is
to use string input like this:

float Real; String A_String_Operator; float Imaginary;
cin >>
"Enter z,"
" ( in the form: Real + Imaginary, "
" spaces required ): " >>
Real >> A_String_Operator >> Imaginary;

Then the user could simply type in something like:
5 + 6

Right, something like that. Likely you'd overload operator>> for
std::complex, and parse the read in string looking for "a + bi", where
a and b are doubles.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #32
Hi Karl Heinz Buchegger,

Re: How I quote people.

You suggested,
" Then prepare to not getting answers.
It is you who wants help, not us. "

Assholes like you are a dime a dozen.

Why don't you go run and hide somewhere ... Please.
Jul 22 '05 #33
Hi tom_usenet,

Re: Prompting for complex numbers.

You suggested,
' parse the read in string looking for "a + bi" '

Right, Only plain C could do that just as well as C++.
Jul 22 '05 #34
On Wed, 2 Jun 2004 09:04:47 -0700, Jeff Relf <Me@Privacy.NET> wrote:
Hi tom_usenet,

Re: Prompting for complex numbers.

You suggested,
' parse the read in string looking for "a + bi" '

Right, Only plain C could do that just as well as C++.

Any language will do it - that's the point! The input that a program
accepts is purely an ability of the program, not the language it is
written in. Parsing code is generally easier in python or perl
(assuming you know them).

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #35

### This discussion thread is closed

Replies have been disabled for this discussion.