Solved

Overloading Operators in c++

Posted on 2011-02-16
12
283 Views
Last Modified: 2012-05-11
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
0
Comment
Question by:v_eman
  • 4
  • 3
  • 2
  • +3
12 Comments
 
LVL 11

Expert Comment

by:MajorBigDeal
ID: 34913803
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
 
LVL 12

Accepted Solution

by:
trinitrotoluene earned 500 total points
ID: 34913843
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
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34913858
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
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34913875
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
 
LVL 11

Expert Comment

by:SAMIR BHOGAYTA
ID: 34914180
Hi, use this code

class MyString
{
  public:
      char member1[100];
      void operator +(MyString val)
      {
           strcat(member1, val.member1);
      }
 };
0
 
LVL 32

Expert Comment

by:sarabande
ID: 34914475
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 53

Expert Comment

by:Infinity08
ID: 34914641
>> 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
 
LVL 32

Expert Comment

by:phoffric
ID: 34914667
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
 
LVL 32

Expert Comment

by:sarabande
ID: 34914759
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
 
LVL 32

Expert Comment

by:sarabande
ID: 34914788
thanks phoffric. warning level 4 gives warning for argument to copy constructor not being const.

Sara
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34914868
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
 
LVL 32

Expert Comment

by:sarabande
ID: 34915175
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

746 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