Reputation: 538
When debugging my program I keep getting these two errors:
main.obj : error LNK2005: "class std::basic_istream > & __cdecl operator>>(class std::basic_istream > &,class Complex &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAVComplex@@@Z) already defined in Imaginary.obj
1>main.obj : error LNK2005: "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class Complex const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABVComplex@@@Z) already defined in Imaginary.obj
I have tried restarting my project to make sure that I created a console application and not something else on accident but that didn't work. Any direction would be greatly appreciated.
Here's my code:
imaginary.h
#ifndef imaginary_h_
#define imaginary_h_
#include <iostream>
class Complex
{
friend std::ostream & operator << (std::ostream& os, const Complex&);
friend std::istream & operator >> (std::istream& is, Complex&);
private:
double real;
double imag;
char op;
public:
double r = real;
double i = imag;
char o = op;
Complex()
{
}
Complex(double r, double i, char o)
{
}
bool userTest();
};
#endif
std::ostream & operator << (std::ostream & os, const Complex & complex)
{
os << complex.r << complex.o << complex.i << "i" << "/n" << "/n";
return os;
}
std::istream & operator >> (std::istream & is, Complex & complex)
{
is >> complex.r >> complex.o >> complex.i;
return is;
}
Imaginary.cpp
#include "imaginary.h"
#include <iostream>
bool Complex::userTest()
{
if (op == '+' || op == '-')
{
return true;
}
else
{
std::cout << "Incorrect operand entry, please enter complex number as x+yi" << "/n" << "/n";
return false;
}
}
main.cpp
#include "imaginary.h"
#include <iostream>
int main()
{
double userInput;
std::cout << "Here you will add or subtract complex numbers." << "/n" << "/n";
do
{
std::cout << "Please enter the real part of you complex number: " << "/n" << "/n";
Complex complex;
std::cin >> complex;
std::cout << "/n" << "/n" << "/n/t" << "Note: Remember to enter your complex number in the format of x+yi to avoid an error";
if (complex.userTest())
{
std::cout << complex << "/n" << "/n";
}
std::cout << "Would you like to perform another complex number operation? " << "/n" << "/n/t";
std::cout << "Choose 1 for Yes and 2 for No" << "/n" << "/n";
std::cin >> userInput;
} while (userInput == 1);
system("pause");
return 0;
}
Upvotes: 6
Views: 7913
Reputation: 57678
You have two options:
inline
.For example, in your header file, imaginary.hpp:
inline // <-- Add this line
std::ostream & operator << (std::ostream & os, const Complex & complex)
{
os << complex.r << complex.o << complex.i << "i" << "/n" << "/n";
return os;
}
inline // <-- Add this line
std::istream & operator >> (std::istream & is, Complex & complex)
{
is >> complex.r >> complex.o >> complex.i;
return is;
}
#endif // imaginary_h_ <-- This line was moved.
Or you can simply move the implementations into your imaginary.cpp file.
Upvotes: 15
Reputation: 6187
The problem is that you have defined
std::ostream & operator<<(std::ostream &os, const Complex &complex) {
os << complex.r << complex.o << complex.i << "i" << "/n" << "/n";
return os;
}
std::istream & operator>>(std::istream &is, Complex &complex) {
is >> complex.r >> complex.o >> complex.i;
return is;
}
in your header file and because this is included in imaginary.cpp
and main.cpp
they are defined multiple times. This violates the single definition rule of C++.
You need to move the implementation of operator <<
and operator >>
to the .cpp
file and only leave the declaration in the header file. This would mean having
std::ostream & operator<<(std::ostream &os, const Complex &complex);
std::istream & operator>>(std::istream &is, Complex &complex);
in the header file after the definition of the class
class Complex {
...
};
and before the ending #endif
. Then in imaginary.cpp
you would have the definition
std::ostream & operator<<(std::ostream &os, const Complex &complex) {
os << complex.r << complex.o << complex.i << "i" << "/n" << "/n";
return os;
}
std::istream & operator>>(std::istream &is, Complex &complex) {
is >> complex.r >> complex.o >> complex.i;
return is;
}
Upvotes: 8
Reputation: 41760
Your error lies in your header guard:
bool userTest();
};
#endif // Here!
std::ostream & operator << (std::ostream & os, const Complex & complex)
{
os << complex.r << complex.o << complex.i << "i" << "/n" << "/n";
return os;
}
When you include the header in your two file, they each compile the function in their respective compilation unit. That's why there's an error at link time.
Your file should look like this:
#ifndef imaginary_h_
#define imaginary_h_
#include <iostream>
class Complex
{
friend std::ostream & operator << (std::ostream& os, const Complex&);
friend std::istream & operator >> (std::istream& is, Complex&);
private:
double real;
double imag;
char op;
public:
double r = real;
double i = imag;
char o = op;
Complex()
{
}
Complex(double r, double i, char o)
{
}
bool userTest();
};
std::ostream & operator << (std::ostream & os, const Complex & complex)
{
os << complex.r << complex.o << complex.i << "i" << "/n" << "/n";
return os;
}
std::istream & operator >> (std::istream & is, Complex & complex)
{
is >> complex.r >> complex.o >> complex.i;
return is;
}
#endif
But two other things:
#pragma once
in addition of your header guard. It should prevent some error while keeping a standard code.Upvotes: -1