Overloading Operators in c++

As beginner, I am trying to write a template class for complex numbers with overloaded constructors and overloaded operators.
I attached two codes, one is errorcode.cpp and the other is correctcode.cpp

1. When I tried to add a constructor that can accept the object of same class and copy the contents, (Is this called copy constructor? )
I have problems with overloading operator +.
(See the commented constructor and its definitions)

2. why? without this  constructor, I can compile the code and run it.

3. and any suggestions on this code, am I using correctly cvect<T> or any redundancy?

thank you.  

correctcode.cpp
errorCode.cpp
v_emanAsked:
Who is Participating?
 
trinitrotolueneConnect With a Mentor Director - Software EngineeringCommented:
everything seems ok. You just need to be careful with the assignment operator
// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
# include <iostream>
using namespace std;
// a class for complex numbers
template <class T>
class cvect
{
public:
       // Constructors
       cvect();
       cvect(T,T);
       cvect(cvect<T>&);
       
       //Overlaoding operators
       cvect<T> operator+(cvect<T>);
       cvect<T>& operator= (const cvect<T>&);  
       void disp();
private:
        T real;
        T image;       
      
};

template <class T>
cvect<T>::cvect()
{
  real=0;
  image=0;            
}

template <class T>
cvect<T>::cvect(T r, T i)
{
  real=r;
  image=i;            
}

template <class T>
cvect<T>::cvect(cvect<T>& arg)
{
  real=arg.real;
  image=arg.image;            
}


template <class T>
cvect<T> cvect<T>::operator+(cvect<T> param) {
  cvect<T> temp;
  temp.real = real + param.real;
  temp.image = image + param.image;
  return (temp);
}

template <class T>
cvect<T>& cvect<T>::operator= (const cvect<T>& arg)
{	
real=arg.real;
image=arg.image;    
return *this;
}


template <class T>
void cvect<T>::disp()
{
cout<<real<<" + i"<<image<<endl;     
}
int main()
{
 cvect<int> a;
 cvect<int> b(3,4);
 cvect<int> c=b;
 a = c + b;
 b.disp();
 b.disp();
 a.disp();
 
 cvect<double> a1;
 cvect<double> b1(3.12,4.18);
 cvect<double> c1=b1;
 
 a1 = c1 + b1;
 b1.disp();
 b1.disp();
 a1.disp();
 
 getchar();
 return 0;   
    
}

Open in new window

0
 
MajorBigDealCommented:
Maybe because you are using operator + inside the definition of operator +.  Just a guess,  it has been about 10 years since I used c++ but I used to get by.
0
 
trinitrotolueneDirector - Software EngineeringCommented:
ignore the #include "stdafx.h"

One important thing you need to consider while using Assignment operators is that you should check for self assignment.

In your code the assignment operator is called for the below line
a = c + b;

The copy constructor comes into play when you are constructing an object for the first time by copying from a different object
cvect<int> c=b; //here's where the copy constructor is called

similarly here is another place where the copy constructor is called
cvect<double> c1=b1;


here is where the assignment operator is called again
a1 = c1 + b1;


Take a look at
http://www.cplusplus.com/articles/jsmith1/








0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
trinitrotolueneDirector - Software EngineeringCommented:
minor correction. you were displaying the wrong variables
// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
# include <iostream>
using namespace std;
// a class for complex numbers
template <class T>
class cvect
{
public:
       // Constructors
       cvect();
       cvect(T,T);
       cvect(cvect<T>&);
       
       //Overlaoding operators
       cvect<T> operator+(cvect<T>);
       cvect<T>& operator= (const cvect<T>&);  
       void disp();
private:
        T real;
        T image;       
      
};

template <class T>
cvect<T>::cvect()
{
  real=0;
  image=0;            
}

template <class T>
cvect<T>::cvect(T r, T i)
{
  real=r;
  image=i;            
}

template <class T>
cvect<T>::cvect(cvect<T>& arg)
{
  real=arg.real;
  image=arg.image;            
}


template <class T>
cvect<T> cvect<T>::operator+(cvect<T> param) {
  cvect<T> temp;
  temp.real = real + param.real;
  temp.image = image + param.image;
  return (temp);
}

template <class T>
cvect<T>& cvect<T>::operator= (const cvect<T>& arg)
{	
real=arg.real;
image=arg.image;    
return *this;
}


template <class T>
void cvect<T>::disp()
{
cout<<real<<" + i"<<image<<endl;     
}
int main()
{
 cvect<int> a;
 cvect<int> b(3,4);
 cvect<int> c=b;
 a = c + b;
 b.disp();
 c.disp();
 a.disp();
 
 cvect<double> a1;
 cvect<double> b1(3.12,4.18);
 cvect<double> c1=b1;
 
 a1 = c1 + b1;
 c1.disp();
 b1.disp();
 a1.disp();
 
 getchar();
 return 0;   
    
}

Open in new window

0
 
SAMIR BHOGAYTAFreelancer and IT ConsultantCommented:
Hi, use this code

class MyString
{
  public:
      char member1[100];
      void operator +(MyString val)
      {
           strcat(member1, val.member1);
      }
 };
0
 
sarabandeCommented:
i don't get problems with neither errorcode.cpp nor correctedcode.cpp. i can uncomment copy constructor and it still compiles and builds.

Sara
0
 
Infinity08Commented:
>> i don't get problems with neither errorcode.cpp nor correctedcode.cpp. i can uncomment copy constructor and it still compiles and builds.

Then you got lucky (probably due to compiler optimizations), but as trinitrotoluene already pointed out, there is an issue with the way the assignment operator is implemented.

The proper signature for it would be :

        cvect<T>& operator=(const cvect<T>&);

ie. it's supposed to return a reference to the resulting (this) object, and take a const reference as argument.


Similarly, you should pass a const reference for the copy constructor and the summation operator.


And (as mentioned by trinitrotoluene) : for copy constructors, it's a good idea to check for self assignment. In this specific case, self assignment will not cause any problems, but it's still a good idea to check for it.


Sorry for repeating you, trinitrotoluene, but it cannot be stressed enough that you need to get the basic plumbing of a class right, or the whole building will come tumbling down some day.
0
 
phoffricCommented:
Sara,
If you are using VS, then change your warning settings to W4 to get warnings.
Or to get errors, set Language -> Disable Language Extensions to /ZaThen every posting here have problems except correctcode.cpp.
0
 
sarabandeCommented:
without this  constructor, I can compile the code and run it.

i assumed compiler or build errors because of that statement. of course trinitrotuelene was right with all his remarks.

Sara
0
 
sarabandeCommented:
thanks phoffric. warning level 4 gives warning for argument to copy constructor not being const.

Sara
0
 
phoffricCommented:
When I build the code in http:#34913875 in VS 2010 Express with warning level 3, but with
    Language -> Disable Language Extensions set to Yes (/Za)
then a couple of errors shown below are issued.

According to Disable Language Extensions :
The Visual C++ compiler offers a number of features beyond those specified in either the ANSI C or ANSI C++ standards. These features are known collectively as Microsoft extensions to C and C++. These extensions are available when the /Ze option is specified, and not available when the /Za option is specified.

So, either MS VS 2010 Express is still not up to ANSI C++ standards or, if these are valid errors, then a little more work needs to be done.
1>------ Rebuild All started: Project: Complex, Configuration: Debug Win32 ------
1>  complexOperator.cpp
1>..\complex\complexoperator.cpp(76): error C2440: 'argument' : cannot convert from 'cvect<T>' to 'cvect<T> &'
1>          with
1>          [
1>              T=int
1>          ]
1>          A non-const reference may only be bound to an lvalue
1>          while checking that elided copy-constructor 'cvect<T>::cvect(cvect<T> &)' is callable
1>          with
1>          [
1>              T=int
1>          ]
1>          ..\complex\complexoperator.cpp(15) : see declaration of 'cvect<T>::cvect'
1>          with
1>          [
1>              T=int
1>          ]
1>          when converting from 'cvect<T>' to 'const cvect<T> &'
1>          with
1>          [
1>              T=int
1>          ]
1>..\complex\complexoperator.cpp(85): error C2440: 'argument' : cannot convert from 'cvect<T>' to 'cvect<T> &'
1>          with
1>          [
1>              T=double
1>          ]
1>          A non-const reference may only be bound to an lvalue
1>          while checking that elided copy-constructor 'cvect<T>::cvect(cvect<T> &)' is callable
1>          with
1>          [
1>              T=double
1>          ]
1>          ..\complex\complexoperator.cpp(15) : see declaration of 'cvect<T>::cvect'
1>          with
1>          [
1>              T=double
1>          ]
1>          when converting from 'cvect<T>' to 'const cvect<T> &'
1>          with
1>          [
1>              T=double
1>          ]
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Open in new window

0
 
sarabandeCommented:
v_eman, i don't think that complex numbers are good sample for using template class. you sensefully could choose float or double type only or the complex type would be incomplete for division and other math operations.

i would implement a complex type with double and would concentrate on making it full operable.

if a class type has no pointer members you better omit implementing a copy constructor and assign operator cause those were added by the compiler if needed.

Sara
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.