
Complex Number
Hello all C++ expert programmer, i have a dumb question.
What is complex number ? What kind of function, complex class should have ?
Below is my program :
Code:
// Header File for complex number
#ifndef _Complex_
#define _Complex_
template <typename T>
class complex
{
T real, imaginary;
public:
complex() : real(0), imaginary(0){}
explicit complex(T real, T imaginary)
: real(real), imaginary(imaginary){}
/* To enforce explicit conversion operation
run successfully if one argument is supplied
*/
complex<T>(const complex<T> &complex)
:real(complex.real),
imaginary(complex.imaginary){}
// Copy Constructor
T& operator=(const complex<T> &complex)
{
if (this != &complex)
{
real = complex.real;
imaginary = complex.imaginary;
} // To avoid selfassignment
return *this;
}
// Assignment Operator
void setReal();
void setImaginary();
T& operator+(complex<T>);
T& operator(complex<T>);
T& operator*(complex<T>);
T& operator/(complex<T>);
~complex(){}
};
#endif
Implementation File :
Code:
#include<iostream>
#include "Complex.h"
using namespace std;
int main(int argc, char *argv[])
{
complex<double> a;
a.setReal();
a.setImaginary();
complex<double> b;
b.setReal();
b.setImaginary();
cout << a.operator+(b);
// Run error, cannot execute
return 0;
}
// 
template<typename T>
void complex<T>::setReal()
{
cout << "Enter the real number : ";
cin >> real;
}
// 
template<typename T>
void complex<T>::setImaginary()
{
cout << "Enter the imaginary number : ";
cin >> imaginary;
}
// 
cout << a.operator+(b);
// Run error, cannot execute
I don't know what happen. It just cannot execute.
Complex.obj : error LNK2001: unresolved external symbol "public: double & __thiscall complex<double>::operator+(class complex<double>)" (??H?$complex@N@@QAEAANV0@@Z)
Thanks for your help.
Your help is greatly appreciated by me and others.

Hi,
you did not implement your + operator.
Since you created a template class, the implementation should be in the *SAME* file, either inlined in the class declaration or outside. Don't implement it in another file, or you have to include it as well. Remember: a template class is not compiled and linked like other classes, but only when referenced in your code. You can even write methods that are not compiling when you reference them, but if you do not reference them you won't find out. It's a pecularity of templates that you got to get used to.
So implement your + operator and you should be cooking with gas...
Cheers,
D

complex number is just an object with two varible re and im.
Define + operator and see.

This is a noob question i ever ask. I forgot to implement the definition.
Thanks for your remind. I will implement it in a same file.

I have implement the definition but come out some errors such as
d:\c++\complex number\complex number\complex.h(45) : error C2440: 'return' : cannot convert from 'complex<T>' to 'double &'
Code:
// Header File for complex number
#ifndef _Complex_
#define _Complex_
template <typename T>
class complex
{
T real, imaginary;
public:
complex() : real(0), imaginary(0){}
explicit complex(T real, T imaginary)
: real(real), imaginary(imaginary){}
/* To enforce explicit conversion operation
run successfully if one argument is supplied
*/
complex<T>(const complex<T> &complex)
:real(complex.real),
imaginary(complex.imaginary){}
// Copy Constructor
T& operator=(const complex<T> &complex)
{
if (this != &complex)
{
real = complex.real;
imaginary = complex.imaginary;
} // To avoid selfassignment
return *this;
}
// Assignment Operator
void setReal();
void setImaginary();
T& operator+(complex<T> second)
{
this>real = real + second.real;
this>imaginary = imaginary + second.imaginary;
return *this;
}
T& operator(complex<T>);
T& operator*(complex<T>);
T& operator/(complex<T>);
~complex(){}
};
#endif
Thanks for your help.

Hi,
a few glitches again:
Code:
T& operator=(const complex<T> &complex) // you call your variable the same as your class!!
// use rhs, or similar instead
// I should be surprised if this code compiles
// I would implement your + operator in the following way
complex<T>& operator+=(const complex<T>& second)
{
real += second.real;
imaginary += second.imaginary;
return *this;
}
// outside the class: global + operator
template <class T>
complex<T> operator + (const complex<T>& lhs, const complex<T>& rhs)
{
complex<T> reval = lhs;
reval += rhs;
return reval;
}
This way you have a symmetric operator and you can use it as you would intuitively.
Hope that helps.
D
BTW: your original error was, that your + operator returned a T rather than a complex<T> ....
DKyb

Life is a short warm moment 
Death is the long cold rest.
Pink Floyd


I think i very stupid because such a simple program also couldn't wrote it well.
I understand few statement that you explain.
T& operator=(const complex<T> &complex) // you call your variable the same as your class!!
I know that complex(){} (constructor) is same as complex<T>(){} but how me this concept couldn't applied to this situation
T& operator+(const complex<T> second(){}
The second unclear is why u further implement + operator as global function.
I really very stupid. Please forgive my stupidness.
Thanks for your help.
Your help is greatly appreciated by me and others.

Hi,
the reason why you should implement a global operator:
Code:
// when you implement a + operator inside the class, like you did, the
// following will happen:
complex<double> c1(1.0,1.0);
complex<double> c2(1.0,2.0);
complex<double> c3 = (c1 + c2); // ooops: c1 is now (0.0,3.0) !!!!
// moreover the operator is not symmetric in that
complex<double> c3 = (c2 + c1); // ooops: c2 is now (0.0,3.0) !!!!
I don't think your questions are at all stupid. Most people stumble across these subtelties of C++ when they learn the language... ;)
Cheers,
D

Thanks for your help. You are really good man.
By the way, i test it according what you say. The first argument (c1 or c2) is override by the result c3. It's so miracle.
Why such matter happen because they all all different object ?
Thanks for your help. I really admire you because you have deep C++ knowledge.

I have did what you told but still will override the first argument of the expression > c=a+b;
a will get override by c.
As i know, return reference is undefined behavior but i feel unclear about this rules.
Someone says cannot return local reference but can return the reference from the paramater. Which one is true ?
Below is my program:
Header File :
Code:
// Header File for complex number
#ifndef _Complex_
#define _Complex_
#include<iostream>
using std::ostream;
template <typename T>
class complex
{
T real, imaginary;
friend ostream& operator<<(ostream& output, const complex<T> any)
{
output << "\nThe result of real is " << any.real
<< "\nThe result of imaginary is " << any.imaginary;
return output;
// Reference is pass by reference without * or & same pass by value;
}
public:
// Complex(){} is same complex<T>(){}
complex<T>() : real(0), imaginary(0){}
explicit complex(T real, T imaginary)
: real(real), imaginary(imaginary){}
/* To enforce explicit conversion operation
run successfully if one argument is supplied
*/
complex<T>(const complex<T> &complex)
:real(complex.real),
imaginary(complex.imaginary){}
// Copy Constructor
complex<T>& operator=(const complex<T> &complex)
{
if (this != &complex)
{
real = complex.real;
imaginary = complex.imaginary;
} // To avoid selfassignment
return *this;
}
// Assignment Operator
void setReal();
void setImaginary();
complex<T>& operator+(complex<T> second)
{
this>real = real + second.real;
this>imaginary = imaginary + second.imaginary;
return *this;
}
complex<T>& operator(complex<T> second)
{
real = second.real;
imaginary = second.imaginary;
return *this;
}
complex<T>& operator*(complex<T> second)
{
real *= second.real;
imaginary *= second.imaginary;
return *this;
}
complex<T>& operator/(complex<T> second)
{
real /= second.real;
imaginary /=second.imaginary;
return *this;
}
~complex(){}
};
template <typename T>
complex<T>& operator+(const complex<T> first, const complex<T> second)
{
complex<T>& reference = first;
reference += second;
return reference;
}
#endif
Implementation File :
Code:
#include<iostream>
#include "Complex.h"
using namespace std;
int main(int argc, char *argv[])
{
complex<double> a;
a.setReal();
a.setImaginary();
complex<double> b;
b.setReal();
b.setImaginary();
/* Explicit Function call
The first argument will override
by result.Exp: a will overrride by result
*/
cout << a+b;
cout << a << b;
// This call must define own insertion operator;
// If have get function no need define <<
/* cout << a.operator(b);
cout << a.operator*(b);
cout << a.operator/(b);*/
// Shortcut cout << a+b
return 0;
}
// 
template<typename T>
void complex<T>::setReal()
{
cout << "Enter the real number : ";
cin >> real;
}
// 
template<typename T>
void complex<T>::setImaginary()
{
cout << "Enter the imaginary number : ";
cin >> imaginary;
}
// 
Thanks for your help.

Hi,
You still have the +  operator implemented as a member.
just change all your arithmetic operatorslike that:
Code:
complex<T>& operator+=(complex<T> second)
{
this>real = real + second.real;
this>imaginary = imaginary + second.imaginary;
return *this;
}
complex<T>& operator=(complex<T> second)
{
real = second.real;
imaginary = second.imaginary;
return *this;
}
complex<T>& operator*=(complex<T> second)
{
real *= second.real;
imaginary *= second.imaginary;
return *this;
}
complex<T>& operator/=(complex<T> second)
{
real /= second.real;
imaginary /=second.imaginary;
return *this;
}
and implement the global operators +,,*,/ in terms of these operators.
Don't implement the +,,/,* operators at all as members.
When you use e.g. += you explitely want the left hand side modified, that's why operator assignment  operators do the right thing.
Code:
complex<double> c1(1.0,1,0);
complex<double> c2(2.0,0.0);
c2 += c1; // c2 is now (3.0,1.0) and c1 unchanged: correct.
Cheers,
D

**** drybelk, i finally understand why the +, , * and / should declared as global because to enforce symmetrical.
Now i have few problem regarding template.
I hope you all can help me out.
Header File.
Code:
// Header File for complex number
#ifndef _Complex_
#define _Complex_
#include<iostream>
using std::ostream;
template<typename T>
class complex;
// Forward Declaration
// symmetrical between first and second
template<typename T>
complex<T>& operator+
(const complex<T>& first, const complex<T>& second);
template <typename T>
class complex
{
T real, imaginary;
public:
friend ostream& operator<<(ostream& output, const complex<T> any)
{
output << "\nThe result of real is " << any.real << "\nThe result of imaginary is " << any.imaginary;
return output;
// Reference is pass by reference without * or & same pass by value;
}
// Complex(){} is same complex<T>(){}
complex<T>() : real(0), imaginary(0){}
explicit complex(T real, T imaginary)
: real(real), imaginary(imaginary){}
/* To enforce explicit conversion operation
run successfully if one argument is supplied
*/
complex<T>(const complex<T> &complex)
:real(complex.real),
imaginary(complex.imaginary){}
// Copy Constructor
complex<T>& operator=(const complex<T> &complex)
{
if (this != &complex)
{
real = complex.real; imaginary = complex.imaginary;
} // To avoid selfassignment
return *this;
}
// Assignment Operator
friend complex<T>& operator +
(const complex<T>& first, const complex<T>& second)
{
complex<T>& result = first;
// reference must be initialized
result = first.real + second.real;
result = first.imaginary + second.imaginary;
return result;
}
void setReal();
void setImaginary();
~complex(){}
};
#endif
Error Message is as follow.
T' was not declared in this scope
template argument 1 is invalid
'T' was not declared in this scope
template argument 1 is invalid
'T' was not declared in this scope
template argument 1 is invalid
invalid type in declaration before ';' token
'int& operator+(const int&, const int&)' must have an argument of class or enu
In function 'complex<double>& operator+(const complex<double>&, const
error: invalid initialization of reference of type 'complex<double>&' from expression of type 'const comple
This is all the error message i got from gcc compiler.
I using kdevelop.
Thanks for your help.
Your help is greatly appreciated by me and others.
Last edited by Peter_APIIT; 07182007 at 05:27 AM.

I don't have gcc to try it myself but why gcc? have you tried to compile it with g++ as well?

I tried it with an IBM compiler that I can use at the moment, because I am at work, (xlc++) in AIX and your code compiles fine.

What the difference between gcc and g++? Gnu Compiler collection(gcc) already included the g++ compiler.
Similar Threads

Replies: 18
Last Post: 12132006, 03:49 PM

By divagoddess in forum C++
Replies: 12
Last Post: 05072006, 10:55 PM

Replies: 7
Last Post: 12022005, 12:29 AM

Replies: 3
Last Post: 08012005, 05:59 AM

By George in forum oracle.general
Replies: 0
Last Post: 04012003, 01:00 AM
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Development Centers
 Android Development Center
 Cloud Development Project Center
 HTML5 Development Center
 Windows Mobile Development Center
