Solved

Trouble overloading operators in C++

Posted on 2007-11-16
29
514 Views
Last Modified: 2013-12-14
I am working on an assignment where I need to overload the +, -, ==, =!, >> and << operators using a Complex number class.  I have the + and - working, but when I try to compile with my == and =! I  am getting errors.  can someone tell me what I have wrong?  

#include <iostream>
 
 using std::cout;
 
 #include"complex1.h"// Complex class definition
 
 // constructor
 Complex::Complex( double realPart, double imaginaryPart )
    : real( realPart ),
      imaginary( imaginaryPart )
 {
    // empty body
 
 } // end Complex constructor
 
 // addition operator
 Complex Complex::operator+( const Complex &operand2 ) const
 {
 return Complex( real + operand2.real,
       imaginary + operand2.imaginary );
 
 } // end function operator+
 
 // subtraction operator
 Complex Complex::operator-( const Complex &operand2 ) const
 {
 return Complex( real - operand2.real,
       imaginary - operand2.imaginary );
 
 } // end function operator-

 std::ostream& operator<<(std::ostream&, const Complex&)
 {

 }
 std::istream& operator>>(std::istream&, const Complex&)
 {

 }
 
 bool Complex::operator==( const Complex &operand2 ) const
 {
       if (real == operand2.real && imaginary == operand2.imaginary)
             return true;
 }
 bool Complex::operator=!( const Complex &operand2 ) const
 {
       if (real =! operand2.real || imaginary =! operand2.imaginary)
             return true;
 }
 // display a Complex object in the form: (a, b)
 void Complex::print() const
 {
    cout << '(' << real << ", " << imaginary << ')';
 
 } // end function


--------------------------
#ifndef COMPLEX1_H
#define COMPLEX1_H
 
class Complex {
 
public:
    Complex( double = 0.0, double = 0.0 );       // constructor
    Complex operator+( const Complex & ) const;  // addition
    Complex operator-( const Complex & ) const;  // subtraction
      Complex operator==( const Complex &operand2 ) const;
      Complex operator=!( const Complex &operand2 ) const;
      std::ostream& operator<<(std::ostream&, const Complex&)const;
      std::istream& operator>>(std::istream&, const Complex&)const;
void print() const;                          // output
 
private:
      double real;       // real part
      double imaginary;  // imaginary part

}; // end class Complex

#endif


these are the errors returned by the compiler
error C2143: syntax error : missing ';' before '!'
error C2460: 'Complex::=' : uses 'Complex', which is being defined
see declaration of 'Complex'
error C2059: syntax error : '('
error C2238: unexpected token(s) preceding ';'
error C2804: binary 'operator <<' has too many parameters
error C2804: binary 'operator >>' has too many parameters
error C2365: 'Complex::=' : redefinition; previous definition was 'data member'
see declaration of 'Complex::='
error C2556: 'bool Complex::operator ==(const Complex &) const' : overloaded function differs only by return type from 'Complex Complex::operator ==(const Complex &) const'
see declaration of 'Complex::operator =='
error C2371: 'Complex::operator ==' : redefinition; different basic types
see declaration of 'Complex::operator =='
error C2143: syntax error : missing ';' before '!'
error C2761: 'int Complex::=' : member function redeclaration not allowed
error C2059: syntax error : '('
error C2143: syntax error : missing ';' before '{'
error C2447: '{' : missing function header (old-style formal list?)
error C2143: syntax error : missing ';' before '!'
error C2460: 'Complex::=' : uses 'Complex', which is being defined
1>        d:\my documents\visual studio 2005\projects\week 11\week 11\complex1.h(6) : see declaration of 'Complex'
error C2059: syntax error : '('
error C2238: unexpected token(s) preceding ';'
error C2804: binary 'operator <<' has too many parameters
error C2804: binary 'operator >>' has too many parameters
error C2365: 'Complex::=' : redefinition; previous definition was 'data member'
see declaration of 'Complex::='
0
Comment
Question by:urobins
  • 16
  • 10
  • 3
29 Comments
 
LVL 13

Accepted Solution

by:
josgood earned 500 total points
Comment Utility
To begin, your header has three issues

Operator is !=, not =!
      Complex operator!=( const Complex &operand2 ) const;

These operators take one arg
      std::ostream& operator<<(const Complex&)const;
      std::istream& operator>>(const Complex&)const;
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
== and != operators return bool
      bool operator==( const Complex &operand2 ) const;
      bool operator!=( const Complex &operand2 ) const;
0
 

Author Comment

by:urobins
Comment Utility
doh!  Thanks!  I'll look at that.
0
 

Author Comment

by:urobins
Comment Utility
Okay here is myheader now, when you say they only take 1 operator I am confused as to what you mean.  Here are my errors...

error C2804: binary 'operator <<' has too many parameters
error C2804: binary 'operator >>' has too many parameters
error C2106: '=' : left operand must be l-value
error C2166: l-value specifies const object

error C2804: binary 'operator <<' has too many parameters
error C2804: binary 'operator >>' has too many parameters

#ifndef COMPLEX1_H
#define COMPLEX1_H
 
class Complex {
 
public:
    Complex( double = 0.0, double = 0.0 );       // constructor
    Complex operator+( const Complex & ) const;  // addition
    Complex operator-( const Complex & ) const;  // subtraction
      bool operator==( const Complex &operand2 ) const;
      bool operator!=( const Complex &operand2 ) const;
      std::ostream& operator<<(std::ostream&, const Complex&);
      std::istream& operator>>(std::istream&, const Complex&);
void print() const;                          // output
 
private:
      double real;       // real part
      double imaginary;  // imaginary part

}; // end class Complex

#endif
0
 

Author Comment

by:urobins
Comment Utility
Oh I just saw your first post :)
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Here are some additional notes...I'll look at the stream operators while you look at this

Main.cpp

Need to match signature (returns bool)
bool Complex::operator!=( const Complex &operand2 ) const
 
-----------------------------
Wrong operator (should be != instead of =!)
 bool Complex::operator!=( const Complex &operand2 ) const
 {
       if (real != operand2.real || imaginary != operand2.imaginary)
             return true;
 }

----------------------------
Need the "else" branch for these
bool Complex::operator==( const Complex &operand2 ) const
 {
       if (real == operand2.real && imaginary == operand2.imaginary)
             return true;
       else
             return false;
 }
 bool Complex::operator!=( const Complex &operand2 ) const
 {
       if (real != operand2.real || imaginary != operand2.imaginary)
             return true;
       else
             return false;
 }

Need accessors and modifiers for private real and imaginary parts in complex1.h
      double Real() { return real; }
      double Imaginary() { return imaginary; }
      void Real(double r) {  real = r; }
      void Imaginary(double i) { imaginary = i; }
0
 

Author Comment

by:urobins
Comment Utility
Here are my errors now.


complex1.cpp(35) : error C2270: '<<' : modifiers not allowed on nonmember functions
complex1.cpp(35) : error C2805: binary 'operator <<' has too few parameters
complex1.cpp(39) : error C2270: '>>' : modifiers not allowed on nonmember functions
complex1.cpp(39) : error C2805: binary 'operator >>' has too few parameters
complex1.cpp(50) : error C2106: '=' : left operand must be l-value
complex1.cpp(50) : error C2166: l-value specifies const object

#ifndef COMPLEX1_H
#define COMPLEX1_H
 
class Complex {
 
public:
    Complex( double = 0.0, double = 0.0 );       // constructor
    Complex operator+( const Complex & ) const;  // addition
    Complex operator-( const Complex & ) const;  // subtraction
      bool operator==( const Complex &operand2 ) const;
      bool operator!=( const Complex &operand2 ) const;
      std::ostream& operator<<(const Complex&)const;
      std::istream& operator>>(const Complex&)const;
void print() const;                          // output
 
private:
      double real;       // real part
      double imaginary;  // imaginary part

}; // end class Complex

#endif


 #include <iostream>
 
 using std::cout;
 
 #include"complex1.h"// Complex class definition
 
 // constructor
 Complex::Complex( double realPart, double imaginaryPart )
    : real( realPart ),
      imaginary( imaginaryPart )
 {
    // empty body
 
 } // end Complex constructor
 
 // addition operator
 Complex Complex::operator+( const Complex &operand2 ) const
 {
 return Complex( real + operand2.real,
       imaginary + operand2.imaginary );
 
 } // end function operator+
 
 // subtraction operator
 Complex Complex::operator-( const Complex &operand2 ) const
 {
 return Complex( real - operand2.real,
       imaginary - operand2.imaginary );
 
 } // end function operator-

 std::ostream& operator<<(const Complex&)const
 {

 }
 std::istream& operator>>(const Complex&)const
 {

 }
 
 bool Complex::operator==( const Complex &operand2 ) const
 {
       if (real == operand2.real && imaginary == operand2.imaginary)
             return true;
 }
 bool Complex::operator!=( const Complex &operand2 ) const
 {
       if (real =! operand2.real || imaginary =! operand2.imaginary)
             return true;
 }
 // display a Complex object in the form: (a, b)
 void Complex::print() const
 {
    cout << '(' << real << ", " << imaginary << ')';
 
 } // end function
0
 

Author Comment

by:urobins
Comment Utility
Ok just saw your post I'll make changes and try again.. Thanks!
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
These two accessors in the header need to be const
      double Real() const { return real; }
      double Imaginary() const { return imaginary; }

and then the stream operators look like this

std::ostream& operator<<(std::ostream& stream, const Complex& value)
 {
      stream << value.Real() << ", " << value.Imaginary() << std::endl;
      return stream;
 }
 std::istream& operator>>(std::istream& stream, Complex& value)
 {
   double r, i;
   stream >> r >> i;
   value.Real(r);
   value.Imaginary(i);
   return stream;  
 }
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
At this point the code is building for me.

Now I would like to explain anything that is confusing to you.

What questions do you have?
0
 

Author Comment

by:urobins
Comment Utility
thanks I'll have a look at that.
0
 

Author Comment

by:urobins
Comment Utility
I'm still getting some compliation errors.  What are the accessors you mentioned for?  I hadn't heard of using those before?  do they go in public or private?  Sorry to ask so many questions I am really trying to grasp this assignment.

what I have is below

#include <iostream>
 
 using std::cout;
 
 #include"complex1.h"// Complex class definition
 
 // constructor
 Complex::Complex( double realPart, double imaginaryPart )
    : real( realPart ),
      imaginary( imaginaryPart )
 {
    // empty body
 
 } // end Complex constructor
 
 // addition operator
 Complex Complex::operator+( const Complex &operand2 ) const
 {
 return Complex( real + operand2.real,
       imaginary + operand2.imaginary );
 
 } // end function operator+
 
 // subtraction operator
 Complex Complex::operator-( const Complex &operand2 ) const
 {
 return Complex( real - operand2.real,
       imaginary - operand2.imaginary );
 
 } // end function operator-

 std::ostream& operator<<(std::ostream& stream, const Complex& value)
 {
      stream << value.real() << ", " << value.imaginary() << std::endl;
      return stream;
 }

 std::istream& operator>>(std::istream& stream, Complex& value)
 {
   double realPart, imaginaryPart;
   stream >> realPart >> imaginaryPart;
   value.real(realPart);
   value.imaginary(imaginaryPart);
   return stream;  
 }

 
 bool Complex::operator==( const Complex &operand2 ) const
 {
       if (real == operand2.real && imaginary == operand2.imaginary)
             return true;
       else
             return false;
 }
 bool Complex::operator!=( const Complex &operand2 ) const
 {
       if (real != operand2.real || imaginary != operand2.imaginary)
             return true;
       else
             return false;
 }
 // display a Complex object in the form: (a, b)
 void Complex::print() const
 {
    cout << '(' << real << ", " << imaginary << ')';
 
 } // end function


#ifndef COMPLEX1_H
#define COMPLEX1_H
 
class Complex {
 
public:
    Complex( double = 0.0, double = 0.0 );       // constructor
    Complex operator+( const Complex & ) const;  // addition
    Complex operator-( const Complex & ) const;  // subtraction
      bool operator==( const Complex &operand2 ) const;
      bool operator!=( const Complex &operand2 ) const;
      std::ostream& operator<<(const Complex&)const;
      std::istream& operator>>(const Complex&)const;
      double real() const { return real; };
    double imaginary() const { return imaginary; };

void print() const;                          // output
 
private:
      double real;
    double imaginary;
 

}; // end class Complex

#endif
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Here is the header I am using
#ifndef COMPLEX1_H
#define COMPLEX1_H
 
class Complex {
 
public:
    Complex( double = 0.0, double = 0.0 );       // constructor
    Complex operator+( const Complex & ) const;  // addition
    Complex operator-( const Complex & ) const;  // subtraction
      bool operator==( const Complex &operand2 ) const;
      bool operator!=( const Complex &operand2 ) const;
      std::ostream& operator<<(const Complex&)const;
      std::istream& operator>>(const Complex&)const;
void print() const;                          // output
      double Real() const { return real; }
      double Imaginary() const { return imaginary; }
      void Real(double r) {  real = r; }
      void Imaginary(double i) { imaginary = i; }
private:
      double real;       // real part
      double imaginary;  // imaginary part

}; // end class Complex

#endif

"Accessors" is a term used for public methods that return (or set) private values.  The "Real" functions in this header are accessors.  Some people like to use "Accessor" and "Modifier", where Accessors return values and Modifiers set them.
0
 

Author Comment

by:urobins
Comment Utility
oh okay I'll take a look thanks!
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 13

Expert Comment

by:josgood
Comment Utility
Accessor and Modifier functions are public, so that the caller can access them.  They allow public access to data that would otherwise be private.  The idea is that by providing accessors and modifiers, you retain control over your private data.  You could, for example, require the caller to provide an access code and have the Accessor or Modifier check that code.  That isn't common, I'm just using that as an example.
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Here are a couple of links that come up when I Google for "why accessor functions".  They say it pretty well.

http://www.vias.org/cppcourse/chap14_04.html

http://www.saskschools.ca/~ehs/HeiseIntra/C/Lesson56.html
0
 

Author Comment

by:urobins
Comment Utility
so accessors are like get and set functions I am used to using.

do they have to be the same name as the private data members?  just curiuos, I want to make sure I understand this.  

0
 

Author Comment

by:urobins
Comment Utility
okay never called them accessors before always referred to them as getX and setX :)
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
Yes, these are the set and get functions you are used to writing.

There is no requirement on the accessor names.  Set and Get are common prefixes.  

I personally don't use them, but that is merely my style.
0
 

Author Comment

by:urobins
Comment Utility
thanks I appreciate the help!
0
 

Author Closing Comment

by:urobins
Comment Utility
The answer was perfect, I can always count on Experts to find my syntax errors :)
0
 
LVL 13

Expert Comment

by:josgood
Comment Utility
You're very welcome! :)
0
 

Author Comment

by:urobins
Comment Utility
one question when I do

cout << y

it doesn't compile, am I doing something wrong?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
The implementation of your stream operators doesn't match how you declared them :

      std::ostream& operator<<(std::ostream& stream, const Complex& value)
      std::istream& operator>>(std::istream& stream, Complex& value)

vs.

      std::ostream& operator<<(const Complex&)const;
      std::istream& operator>>(const Complex&)const;

They should match !
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> it doesn't compile, am I doing something wrong?

If my previous post doesn't solve the error, can you post the error and the code ?
0
 

Author Comment

by:urobins
Comment Utility
as soon as I make my .cpp match the .h (adding the std::ostream& stream, and std::istream& stream) I get compilation errors

complex1.h(16) error C2804: binary 'operator <<' has too many parameters
complex1.h(17) : error C2804: binary 'operator >>' has too many parameters
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
Sorry ... I didn't notice that you didn't declare them as friends :

class Complex {
//<SNIP>

      friend std::ostream &operator<<(std::ostream &stream, const Complex &value);
      friend std::istream &operator>>(std::istream &stream, Complex &value);

//<SNIP>
}; // end class Complex

std::ostream &operator<<(std::ostream &stream, const Complex &value) {
      stream << value.real << ", " << value.imaginary << std::endl;
      return stream;
}

std::istream &operator>>(std::istream &stream, Complex &value) {
      double realPart, imaginaryPart;
      stream >> realPart >> imaginaryPart;
      value.real = realPart;
      value.imaginary = imaginaryPart;
      return stream;  
}
0
 

Author Comment

by:urobins
Comment Utility
thanks, I'll try that!  Forgot about the friend thing.
0
 

Author Comment

by:urobins
Comment Utility
that was it!  Thanks so much!
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now