Overloading the "=" operator for Complex numbers

P

Phlip

Jeff said:
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.
 
J

Jeff Relf

Hi Phlip,

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

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.
 
J

Jeff Relf

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; }
 
J

Jeff Relf

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.
 
P

Phlip

Jeff said:
Is it possible to use any symbol I want
to define an operator, e.g.:
Complex & Complex::eek:perator $ ( 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;
 
J

Jeff Relf

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.
 
P

Phlip

Jeff said:
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 >

Read the book /Accelerated C++/.
 
W

Wouter Lievens

Pmb said:
I didn't say that I refuse to consider const

Constness is a very important part of overloading. You cannot learn operator
overloading without constness. You simply HAVE to use it.
 
P

Pmb

Wouter Lievens said:
Constness is a very important part of overloading. You cannot learn operator
overloading without constness. You simply HAVE to use it.

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
in all cases of operator over loading.

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::eek:perator+( Complex &z )
{
return Complex( re + z.re, im + z.im );
}

const Complex& Complex::eek:perator=( 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
 
J

Jeff Relf

Hi Phlip,

You noted,
" But if you [ overloaded the ] operator !=,
that would break much code
that uses != with two integer arguments,
so overloading an operator would indeed be difficult. "

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.
 
J

Jeff Relf

Hi Pmb ( Pete ), [ Posted & e-mailed ]

You showed: Complex operator + ( Complex & ) ;

and: z2 = a + b + c ;

And your output: z = ( 10, 10 )
( Which showed that it worked as expected )

And then you asked Wouter Lievens,
' Please explain what you mean by
" You simply HAVE to use it. "
when the program works as I expected it to. '

In light of your results, That is an interesting question.

If it works it works.

Perhaps Lievens is saying that it shouldn't work.
( i.e. He's taking a moral stand )

Maybe this is what Lievens was talking about:

Operands are always pushed onto a stack.
A stack is a temporary location to place things.

Later on, those operands get popped off the stack.

C++ doesn't ( or shouldn't ? ) want people to
access those items after that
because they are no longer in existence.

For example:

int & In_A_Stack ( ) {
// 1 here is in a temporary location, i.e. 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; }

But this case doesn't seem to apply
to your immediate explorations.
 
E

E. Robert Tisdale

Pmb said:
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
[snip]

cat Complex.cc
#include <iostream>

class Complex {
private:
// representation
float re;
float im;
public:
// functions
Complex conjugate(void);
float magnitude(void);
friend
std::eek:stream& operator<<(std::eek:stream&, const Complex&);
// operators
Complex operator*(const Complex&);
Complex operator/(const Complex&);
Complex operator+(const Complex&);
Complex operator-(const Complex&);
Complex operator=(const Complex&);
// constructors
Complex(float = 0, float = 0);
};

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

Complex Complex::eek:perator=(const Complex &z) {
re = z.re;
im = z.im;
return *this;
}
g++ -Wall -ansi -pedantic -c Complex.cc

It seems to work just fine for me.
 
K

Karl Heinz Buchegger

Jeff said:
Hi Phlip,

You noted,
" But if you [ overloaded the ] operator !=,
that would break much code
that uses != with two integer arguments,
so overloading an operator would indeed be difficult. "

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.
 
K

Karl Heinz Buchegger

Pmb said:
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
in all cases of operator over loading.

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::eek:perator+( Complex &z )
{
return Complex( re + z.re, im + z.im );
}

const Complex& Complex::eek:perator=( 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

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:
I had no accident ...
 
T

tom_usenet

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 )

If you're parsing input, the only operator overloading of importance
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
 
J

Jeff Relf

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.
 
J

Jeff Relf

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++.
 
T

tom_usenet

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top