Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Already defined error with operator overloading

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;
}
like image 819
Brian Roper Avatar asked Aug 26 '15 16:08

Brian Roper


2 Answers

You have two options:

  1. Move implementation of operator methods to a single cpp file
  2. Or declare the implementations as 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.

like image 118
Thomas Matthews Avatar answered Sep 19 '22 02:09

Thomas Matthews


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;
}
like image 31
IKavanagh Avatar answered Sep 19 '22 02:09

IKavanagh