3

I'm trying to write some code for simple complex number manipulation. I'm using a template class and I'm having trouble overloading operators (specifically +,-,*,/). I'm trying to declare the overload inside my template class, and then define them after in the same header file.

My header code is as follows:

#ifndef MY_CLASS_H
#define MY_CLASS_H

template <class T> class complex
{

private:
    T re,im;
public:
    // Constructors & destructor
    complex(){re=im=0;}
    complex(T r, T i){re=r; im=i;}
    ~complex(){}

    // Return real component
    T realcomp() const {return re;}
    // Return imaginary component
    T imagcomp() const {return im;}


    // Overload + operator for addition 
    complex<T> operator+(const complex<T> &C);

....

};
#endif


#include<iostream>
#include<cmath>
using namespace std;

template <class T> complex<T>& complex<T>::operator+(const complex &C){
complex<T> A(re+C.realcomp(),im+C.imagcomp());
return A;
}

This returns errors that I have so far been unable to solve and I'm not entirely sure where I've gone wrong. A mixture of me being a beginner to C++ and trying to puzzle together solutions to other issues on this website has probably meant that my code is a bit of a mess - I apologise!

Any help would be greatly appreciated.

QuantumO
  • 187
  • 2
  • 12

4 Answers4

2

The declaration for complex<T>::operator+ is returning a complex<T> while the definition is returning a complex<T>&. You want to return the object by value, not reference.

Also, template classes must have their function definitions in the header file, since the compiler needs to be able to see these when instantiating the templates, so move the operator+ definition to the header file.

You should also use constructor initialization lists to initialize the member variables.

template <class T> class complex
{
private:
    T re,im;
public:
    // Constructors & destructor
    complex() : re(), im() {}
    complex( const T& r, const T& i ) : re(r), im(i) {}
    ~complex(){}

    // Return real component
    T realcomp() const {return re;}
    // Return imaginary component
    T imagcomp() const {return im;}


    // Overload + operator for addition 
    complex<T> operator+(const complex<T> &C)
    {
       return complex<T>( re + C.realcomp(), im + C.imagcomp() );
    }
};
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Thanks. Just what I was looking for! Out of interest, what advantages are there if I use constructor initialization lists to initialize the member variables? – QuantumO Apr 13 '12 at 16:50
  • 1
    @user1331900 The answer to [this question](http://stackoverflow.com/questions/4589237/c-initialization-lists) sums it up nicely – Praetorian Apr 13 '12 at 17:26
0

You mismatched the declaration with the definition. Change this line:

template <class T> complex<T>& complex<T>::operator+(const complex &C){

to this

template <class T> complex<T> complex<T>::operator+(const complex &C){

(Note the missing "&")

user1202136
  • 11,171
  • 4
  • 41
  • 62
0

This should work:

template <class T> complex<T> complex<T>::operator+(const complex<T> &C){ 
  complex<T> A(re+C.realcomp(),im+C.imagcomp()); 
  return A; 
} 

The return value is declared to be an object in the class and the patameter is missing the template parameter

Attila
  • 28,265
  • 3
  • 46
  • 55
0

you are returning a local variable as reference. plus the declaration are different:

you declare to return a complex while on definition you return a complex&

andrea.marangoni
  • 1,499
  • 8
  • 22