Operator Overloading

I have code here that I am trying to understand operator overloading, I have hit a road block with an error I don't understand fully. The error has 3 LNK2019 errors on it, reading unresolved external symbol. I want to know what the error is and how I can fix it. Thanks for your help in advance.

This is my implementation code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
ComplexNumber::ComplexNumber()
{
	double complexNumberValue = 0.00;
	double realNumberValue = 0.00;
}

ComplexNumber::ComplexNumber(double real, double imaginary)
{
	realNumberValue = real;
	complexNumberValue = imaginary;
}

ComplexNumber ComplexNumber::operator*(const ComplexNumber& rho) const
{
	double newValue = realNumberValue * rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;

}

ComplexNumber ComplexNumber::operator+(const ComplexNumber& rho) const
{
	double newValue = realNumberValue + rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;
}

ComplexNumber ComplexNumber::operator-(const ComplexNumber& rho) const
{
	double newValue = realNumberValue - rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;
}

ComplexNumber ComplexNumber::operator/(const ComplexNumber& rho) const
{
	double newValue = realNumberValue / rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;
}

ComplexNumber ComplexNumber::operator=(const ComplexNumber& rho)
{
	realNumberValue = rho.realNumberValue;
	return *this;
}

bool operator==(const ComplexNumber& leftOp, const ComplexNumber& rightOp)
{
	if (leftOp.getValue() == rightOp.getValue())
	{
		return true;
	}
	else
	{
		return false;
	}
}

ostream& operator<<(ostream& out, const ComplexNumber& rho)
{
	out << rho.getValue();
	return out;
}


This is my driver code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int main()
{
	// Create complex numbers to do arithmentic with
	ComplexNumber cm1(1, 2);
	ComplexNumber cm2(1, -2);

	// test addition operator
	ComplexNumber cm3 = cm1 + cm2;
	cout << cm3 << endl;

	// test subtraction operator
	ComplexNumber cm4 = cm1 - cm2;
	cout << cm4 << endl;

	// test multiplication operator
	ComplexNumber cm5 = cm1 * cm2;
	cout << cm5 << endl;

	// test division operator
	ComplexNumber cm6 = cm1 / cm2;
	cout << cm6 << endl;

	// test assignment operator
	cm6 = cm5;
	cout << cm6 << endl;

	// test comparison operator
	if (cm1 == cm2)
		cout << "\nThey are equal.\n";
	else
		cout << "\nThey are not equal.";

	ComplexNumber cm8(1, 2);
	if (cm1 == cm8)
		cout << "\nThey are equal.\n";
	else
		cout << "\nThey are not equal.";

	system("PAUSE");
	return 0;
}


Header file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <stdexcept>

using namespace std;

class ComplexNumber
{
public:
	//Constructor
	//Purpose: Set the value of ComplexNumber to 0
	//Parameters: None
	//Returns: None
	ComplexNumber();

	//Parameterized Constructor
	//Purpose: Set the value of ComplexNumber to the parameter
	//Parameters: A double, and a double
	//Returns: None
	ComplexNumber(double, double);

	//getValue
	//Purpose:Getter for complexNumberValue
	//Parameters: None
	//Returns: the double value of object
	double getValue() const;

	//plusOverload
	//Purpose: Overload the + operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the sum
	ComplexNumber operator+(const ComplexNumber&) const;

	//minusOverload
	//Purpose: Overload the - operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the difference
	ComplexNumber operator-(const ComplexNumber&) const;

	//multiplicationOverload
	//Purpose: Overload the * operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the product
	ComplexNumber operator*(const ComplexNumber&) const;

	//divisionOverload
	//Purpose: Overload the / operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the quotient
	ComplexNumber operator/(const ComplexNumber&) const;

	//assignment
	//Purpose: Overload the = operator
	//Parameters: The two ComplexNumbers we want to assign
	//Returns: 
	ComplexNumber operator=(const ComplexNumber&);

	//comparison
	//Purpose: Overload the == operator 
	//Parameters: The two ComplexNumbers we want to compare
	//Returns: 
	bool operator==(const ComplexNumber&) const;

private:
	double complexNumberValue;
	double realNumberValue;
};

//Independant Functions

//streamInsertionOverload
//Purpose: Overload the stream insertion operator
//Parameters: The stream object to read from, and object to read to
//Returns:The stream
ostream& operator<<(const ostream&, const ComplexNumber&);
Last edited on
The error has 3 LNK2019 errors on it, reading unresolved external symbol
And which lines this errors points at?
There are no lines indicated, or I would have put them on here. Here is the error's.

Error 1 error LNK2019: unresolved external symbol "public: bool __thiscall ComplexNumber::operator==(class ComplexNumber const &)const " (??8ComplexNumber@@QBE_NABV0@@Z) referenced in function _main

Error 2 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > const &,class ComplexNumber const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABV01@ABVComplexNumber@@@Z) referenced in function _main

Error 3 error LNK2019: unresolved external symbol "public: double __thiscall ComplexNumber::getValue(void)const " (?getValue@ComplexNumber@@QBENXZ) referenced in function "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class ComplexNumber const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVComplexNumber@@@Z)

Error 4 error LNK1120: 3 unresolved externals
Show your header file. Looks like you either did not include function declarations of made a mistake in them.
There is my header file.
1) getValue() is not implemented at all
2) Declaration/definition mismatch:
1
2
3
4
//Declaration:
ostream& operator<<(const ostream&, const ComplexNumber&);
//Definition:
ostream& operator<<(ostream& out, const ComplexNumber& rho)

3) Either move comparsion operator from your class, or make his definition a part of class too like other operators.
Okay so with that recommendation here is my new header file, but I am receiving other errors from my implementation code. I am not understanding what to place in the implementation file for this comparison operator, what I have now is giving me different errors.

New header file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <stdexcept>

using namespace std;

class ComplexNumber
{
public:
	//Constructor
	//Purpose: Set the value of ComplexNumber to 0
	//Parameters: None
	//Returns: None
	ComplexNumber();

	//Parameterized Constructor
	//Purpose: Set the value of ComplexNumber to the parameter
	//Parameters: A double, and a double
	//Returns: None
	ComplexNumber(double, double);

	//getValue
	//Purpose:Getter for complexNumberValue
	//Parameters: None
	//Returns: the double value of object
	double getValue() const;

	//plusOverload
	//Purpose: Overload the + operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the sum
	ComplexNumber operator+(const ComplexNumber&) const;

	//minusOverload
	//Purpose: Overload the - operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the difference
	ComplexNumber operator-(const ComplexNumber&) const;

	//multiplicationOverload
	//Purpose: Overload the * operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the product
	ComplexNumber operator*(const ComplexNumber&) const;

	//divisionOverload
	//Purpose: Overload the / operator 
	//Parameters: The ComplexNumber on the right side of the operator
	//Returns: A new ComplexNumber object containing the quotient
	ComplexNumber operator/(const ComplexNumber&) const;

	//assignment
	//Purpose: Overload the = operator
	//Parameters: The two ComplexNumbers we want to assign
	//Returns: 
	ComplexNumber operator=(const ComplexNumber&);

private:
	double complexNumberValue;
	double realNumberValue;
};

//Independant Functions

//comparison
//Purpose: Overload the == operator 
//Parameters: The two ComplexNumbers we want to compare
//Returns: 
bool operator==(const ComplexNumber&, const ComplexNumber&);

//streamInsertionOverload
//Purpose: Overload the stream insertion operator
//Parameters: The stream object to read from, and object to read to
//Returns:The stream
ostream& operator<<(const ostream&, const ComplexNumber&);


New implementation code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "ComplexNumbers.h"

ComplexNumber::ComplexNumber()
{
	double complexNumberValue = 0.00;
	double realNumberValue = 0.00;
}

ComplexNumber::ComplexNumber(double real, double imaginary)
{
	realNumberValue = real;
	complexNumberValue = imaginary;
}

ComplexNumber ComplexNumber::operator*(const ComplexNumber& rho) const
{
	double newValue = realNumberValue * rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;

}

ComplexNumber ComplexNumber::operator+(const ComplexNumber& rho) const
{
	double newValue = realNumberValue + rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;
}

ComplexNumber ComplexNumber::operator-(const ComplexNumber& rho) const
{
	double newValue = realNumberValue - rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;
}

ComplexNumber ComplexNumber::operator/(const ComplexNumber& rho) const
{
	double newValue = realNumberValue / rho.getValue();
	ComplexNumber newNumber(newValue, complexNumberValue);
	return newNumber;
}

ComplexNumber ComplexNumber::operator=(const ComplexNumber& rho)
{
	realNumberValue = rho.realNumberValue;
	return *this;
}

bool operator==(const ComplexNumber& leftOp, const ComplexNumber& rightOp)
{
	if (leftOp.getValue() == rightOp.getValue())
	{
		return true;
	}
	else
	{
		return false;
	}
}

ostream& operator<<(ostream& out, const ComplexNumber& rho)
{
	out << rho.getValue();
	return out;
}

double ComplexNumber::getValue() const
{
	return realNumberValue;
}


New Error
Error 1 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > const &,class ComplexNumber const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABV01@ABVComplexNumber@@@Z) referenced in function _main

Last edited on
You did not move comparsion operator (==) but for some reason moved out output operator (<<) which cannot be a class member.
I included the wrong code, here is the updated code with the == out of the class. I included the new error in the post, but I don't understand how to clean up the definition of the << operator.
Last edited on
I post it again: there should be no difference in declaration and definition. And in your code there is one. Look:
1
2
3
4
//Declaration:
ostream& operator<<(const ostream&    , const ComplexNumber&    )
//Definition:
ostream& operator<<(      ostream& out, const ComplexNumber& rho)
Reply okay I figured out how to clean up that definition, by removing the const call from the header file, those are now lined up. But I am not getting the output that I need, I am supposed to get a text file that reads:

2
4i
5
-0.6 + 0.8i
5

They are not equal.
They are equal.
Press any key to continue . . .

Mine reads:
2
0
1
1
1
They are equal.

They are equal.
Press any key to continue . . .

I am not sure why they are so different, from my expected results.
Your comparsion opeator compares only real parts.
Your output operator outputs only real part. Multiplication and division are incorrect too (They multiply real parts and just copy imaginary from left hand operand)
I am not sure how to re factor them to get imaginary numbers to work with it. What would you recommend I change to get those functions to do that?

My idea is to mark them as a "friend" so I can add more parameters to them.
Last edited on
Add function to get imaginary part from complex number.
Look at the standard library complex number for reference: http://en.cppreference.com/w/cpp/numeric/complex
This is what I have changed my division and multiplication to:
1
2
3
4
5
6
7
8
9
10
11
12
13
ComplexNumber ComplexNumber::operator/(const ComplexNumber& rho) 
{
	double realNumber = realNumberValue / rho.realNumberValue;
	double complexNumber = complexNumberValue / rho.complexNumberValue;
	return ComplexNumber(realNumber, complexNumber);
}

ComplexNumber ComplexNumber::operator*(const ComplexNumber& rho) 
{
	double realNumber = realNumberValue * rho.realNumberValue;
	double complexNumber = complexNumberValue * rho.complexNumberValue;
	return ComplexNumber(realNumber, complexNumber);
}

I know that I need to change my << overload to handle the output, but I don't understand what I need to change, I have studied the material listed above but am not certain how to change mine to accept that. This is the only hint I have to get the << to work correctly.

If the value of the real part is zero, do not output the zero, just output the value of the imaginary part, followed by the i.
If the value of the imaginary part is zero, do not output the zero, just output the value of the real part.
If both the real part and the imaginary part are zero, just output a zero.
If the imaginary part is negative your output should be of the form a - bi.
First of all your multiplication/division is still incorrect.
http://mathworld.wolfram.com/ComplexMultiplication.html

Just do what required:
Check if both real and imaginary parts are 0. If so, output 0.
Else check if real part 0. If not, output real part.
Now check if imaginary part is 0.
If not, output imaginary part and i.
Thanks for pointing that out, would this be a better representation of the division?

1
2
3
4
5
6
7
	double div = (rho.realNumberValue*rho.realNumberValue) + (rho.complexNumberValue*rho.complexNumberValue);
	ComplexNumber tmp;
	tmp.realNumberValue = (realNumberValue*rho.realNumberValue) + (complexNumberValue*rho.complexNumberValue);
	tmp.realNumberValue /= div;
	tmp.complexNumberValue = (complexNumberValue*rho.realNumberValue) - (realNumberValue*rho.complexNumberValue);
	tmp.complexNumberValue /= div;
	return tmp;
I now get a compiler error, and am not sure why, it successfully outputted the first 3 and then caused the error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ostream& operator<<(ostream& out, const ComplexNumber& rho)
{
	if (rho.complexNumberValue && rho.complexNumberValue == 0)
	{
		out;//return zero
	}
	if (rho.realNumberValue == 0)
	{
		out << rho.complexNumberValue << "i";
		return out;//return imaginary part followed by i
	}
	if (rho.complexNumberValue == 0)
	{
		out << rho.realNumberValue;
		return out;//return real part
	}
	if (rho.complexNumberValue < 0)
	{
		out << (rho.realNumberValue - rho.complexNumberValue) << "i";
		return out;//output should be in form a - bi
	}
}
Last edited on
I now get a compiler error
Which error? Which line does it refers to?
Topic archived. No new replies allowed.