Defining an overloaded outstream operator outside a class - c++

Here is some simple code that I wrote. It simply copies an object and displays it data functions with an overloaded operator.
//Base
#include<iostream>
#include<istream>
#include<ostream>
using std::ostream;
using std::istream;
using namespace std;
class Sphere{
public:
Sphere(double Rad = 0.00, double Pi = 3.141592);
~Sphere();
Sphere(const Sphere& cSphere)
//overloaded output operator
friend ostream& operator<<(ostream& out, Sphere &fSphere);
//member function prototypes
double Volume();
double SurfaceArea();
double Circumference();
protected:
double dRad;
double dPi;
};
//defining the overloaded ostream operator
ostream& operator<<(ostream& out, Sphere& fSphere){
out << "Volume: " << fSphere.Volume() << '\n'
<< "Surface Area: " << fSphere.SurfaceArea() << '\n'
<< "Circumference: " << fSphere.Circumference() << endl;
return out;
}
The member functions are defined in a .cpp file. The problem is that when I compile this program I am told
there are multiple definitions of operator<<(ostream& out, Sphere& fSphere)
This is strange because the outstream operator is a non-member function so it should be able to be defined out of the class. Yet the program works well when I define this operator inside the class. Whats going on?

It seems you defined the operator in a header file and include this header in multiple cpp modules. or you include one cpp module with the function definition in other cpp module.
Usually the error mesage shows where a function is multiple defined. So reread all lines of the error message
Take into account that it would be better to declare the operator as
ostream& operator<<(ostream& out, const Sphere &fSphere);

Looks like the code you presented if the header file. And it contains the definition of operator<<, so any file including your header has its own copy of this definition, hence "multiple definitions" error. Add the keyword inline to your function, or move the function to .cpp file.

Related

Use non-member functions in Qt [duplicate]

Given this code sample:
complex.h :
#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
class Complex
{
public:
Complex(float Real, float Imaginary);
float real() const { return m_Real; };
private:
friend std::ostream& operator<<(std::ostream& o, const Complex& Cplx);
float m_Real;
float m_Imaginary;
};
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
#endif // COMPLEX_H
complex.cpp :
#include "complex.h"
Complex::Complex(float Real, float Imaginary) {
m_Real = Real;
m_Imaginary = Imaginary;
}
main.cpp :
#include "complex.h"
#include <iostream>
int main()
{
Complex Foo(3.4, 4.5);
std::cout << Foo << "\n";
return 0;
}
When compiling this code, I get the following error:
multiple definition of operator<<(std::ostream&, Complex const&)
I've found that making this function inline solves the problem, but I don't understand why. Why does the compiler complain about multiple definition? My header file is guarded (with #define COMPLEX_H).
And, if complaining about the operator<< function, why not complain about the public real() function, which is defined in the header as well?
And is there another solution besides using the inline keyword?
The problem is that the following piece of code is a definition, not a declaration:
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
You can either mark the function above and make it "inline" so that multiple translation units may define it:
inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
Or you can simply move the original definition of the function to the "complex.cpp" source file.
The compiler does not complain about "real()" because it is implicitly inlined (any member function whose body is given in the class declaration is interpreted as if it had been declared "inline"). The preprocessor guards prevent your header from being included more than once from a single translation unit ("*.cpp" source file"). However, both translation units see the same header file. Basically, the compiler compiles "main.cpp" to "main.o" (including any definitions given in the headers included by "main.cpp"), and the compiler separately compiles "complex.cpp" to "complex.o" (including any definitions given in the headers included by "complex.cpp"). Then the linker merges "main.o" and "complex.o" into a single binary file; it is at this point that the linker finds two definitions for a function of the same name. It is also at this point that the linker attempts to resolve external references (e.g. "main.o" refers to "Complex::Complex" but does not have a definition for that function... the linker locates the definition from "complex.o", and resolves that reference).
Move implementation to complex.cpp
Right now after including this file implementation is being compiled to every file.
Later during linking there's a obvious conflict because of duplicate implementations.
::real() is not reported because it's inline implicitly (implementation inside class definition)
I was having this problem, even after my source and header file were correct.
It turned out Eclipse was using stale artifacts from a previous (failed) build.
To fix, use Project > Clean then rebuild.
An alternative to designating a function definition in a header file as inline is to define it as static. This will also avoid the multiple definition error.

Operator overloading on the global scope in qt/c++ is giving me the multiple definition compile error [duplicate]

Given this code sample:
complex.h :
#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
class Complex
{
public:
Complex(float Real, float Imaginary);
float real() const { return m_Real; };
private:
friend std::ostream& operator<<(std::ostream& o, const Complex& Cplx);
float m_Real;
float m_Imaginary;
};
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
#endif // COMPLEX_H
complex.cpp :
#include "complex.h"
Complex::Complex(float Real, float Imaginary) {
m_Real = Real;
m_Imaginary = Imaginary;
}
main.cpp :
#include "complex.h"
#include <iostream>
int main()
{
Complex Foo(3.4, 4.5);
std::cout << Foo << "\n";
return 0;
}
When compiling this code, I get the following error:
multiple definition of operator<<(std::ostream&, Complex const&)
I've found that making this function inline solves the problem, but I don't understand why. Why does the compiler complain about multiple definition? My header file is guarded (with #define COMPLEX_H).
And, if complaining about the operator<< function, why not complain about the public real() function, which is defined in the header as well?
And is there another solution besides using the inline keyword?
The problem is that the following piece of code is a definition, not a declaration:
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
You can either mark the function above and make it "inline" so that multiple translation units may define it:
inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
Or you can simply move the original definition of the function to the "complex.cpp" source file.
The compiler does not complain about "real()" because it is implicitly inlined (any member function whose body is given in the class declaration is interpreted as if it had been declared "inline"). The preprocessor guards prevent your header from being included more than once from a single translation unit ("*.cpp" source file"). However, both translation units see the same header file. Basically, the compiler compiles "main.cpp" to "main.o" (including any definitions given in the headers included by "main.cpp"), and the compiler separately compiles "complex.cpp" to "complex.o" (including any definitions given in the headers included by "complex.cpp"). Then the linker merges "main.o" and "complex.o" into a single binary file; it is at this point that the linker finds two definitions for a function of the same name. It is also at this point that the linker attempts to resolve external references (e.g. "main.o" refers to "Complex::Complex" but does not have a definition for that function... the linker locates the definition from "complex.o", and resolves that reference).
Move implementation to complex.cpp
Right now after including this file implementation is being compiled to every file.
Later during linking there's a obvious conflict because of duplicate implementations.
::real() is not reported because it's inline implicitly (implementation inside class definition)
I was having this problem, even after my source and header file were correct.
It turned out Eclipse was using stale artifacts from a previous (failed) build.
To fix, use Project > Clean then rebuild.
An alternative to designating a function definition in a header file as inline is to define it as static. This will also avoid the multiple definition error.

C++ code generating errors LNK2005 & LNK1169 on VS2019

The following code generates errors LNK2005 & LNK1169 on Visual Studio 2019.
LNK2005: "void__cdecl OverloadingPlus(void)" (?OverloadingPlus##YAXXZ) already defined in main.obj
LNK1169: one or more multiply defined symbols found
I reached this point by following a course on Udemy, where the instructor seems to have no problems with it.
Similar questions seem to be related to using global variables, defining functions in the header file, not using #ifndef guards... but as far as I can tell, that doesn't seem to be the case.
This problem started appearing only after the operator+ overload was included, but the operator<< doesn't trigger any errors, even though they have been declared and defined in the same manner.
Interestingly enough, if I remove any reference to OverloadingPlus.h file, and add #include Complex.h to main.cpp, the problem goes away.
I fail to see how including Complex.h in OverloadingPlus.h is contributing to a multiple definition of the operator+ exclusively, even though it is only included once in the entire project and the definitions are implemented in Complex.cpp and not in the header file, as pointed out in answers to similar problems.
Also tried surrounding the content of OverloadingPlus.h with an #ifndef statement just to make sure it is only used once which did not change a thing.
I attempted to declare a diferent operator+ overload inside the class (you can see it commented out), but it produces the same errors.
Commented all references to any other files trying to make sure Complex definitions are only included once. Didn't help either.
The code is the following:
main.cpp
//#include "OverloadingAssignmentOperator.h"
//#include "OverloadingLeftBitShiftOperator.h"
//#include "ComplexNumberClass.h"
#include "OverloadingPlus.h"
int main() {
//OverloadingAssignmentOperator();
//OverloadingLeftBitShiftOperator();
//ComplexNumberClass();
OverloadingPlus();
return 0;
}
OverloadingPlus.h
#ifndef OVERLOADING_PLUS_H
#define OVERLOADING_PLUS_H
#include "Complex.hpp"
using namespace complex;
void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
#endif
Complex.hpp
#ifndef COMPLEX_HPP
#define COMPLEX_HPP
#include <iostream>
namespace complex {
class Complex {
private:
double real;
double imaginary;
public:
Complex();
Complex(double, double);
Complex(const Complex&);
const Complex& operator=(const Complex& other);
//const Complex operator+(const Complex& r);
double getReal() const { return real; }
double getImaginary() const { return imaginary; }
};
Complex operator+(const Complex& l, const Complex& r);
std::ostream& operator<<(std::ostream& out, const Complex& c);
}
#endif // !__COMPLEX_HPP__
Complex.cpp
#include "Complex.hpp"
namespace complex {
Complex::Complex() : real(0), imaginary(0) {}
Complex::Complex(double r, double i) : real(r), imaginary(i) {}
Complex::Complex(const Complex& other) {
std::cout << "Copy constructor..." << std::endl;
real = other.real;
imaginary = other.imaginary;
}
const Complex& Complex::operator=(const Complex& other) {
real = other.real;
imaginary = other.imaginary;
return *this;
}
//const Complex Complex::operator+(const Complex& r) {
// return Complex(real + r.getReal(), imaginary + r.getImaginary());
//}
//
Complex operator+(const Complex& l, const Complex& r) {
return Complex(l.getReal()+r.getReal(), l.getImaginary()+r.getImaginary());
}
std::ostream& operator<<(std::ostream& out, const Complex& c) {
out << "(" << c.getReal() << "," << c.getImaginary() << ")";
return out;
}
}
The issue seems to be related to VS2019. Renaming the file to something different, rebuilding the project and renaming the file back to its original name fixed the issue.
While using inline as others suggested did circumvent the issue, it does not solve this specific problem as the conflicting file was not being included multiple times.
You forgot to "inline" your OverloadingPlus.
inline void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
should make the linker error go away.
What probably happened is: You have included "OverloadingPlus.h" in more than one compilation unit (although you failed to provide all instances of your #include in your question).
Every time you include "OverloadingPlus.h" in one of your .cpp files, you add another definition for void OverloadingPlus to your program. The linker detects this and cannot decide on "the right one" and so gives an error.

Multiple definition of function (in derived class) [duplicate]

Given this code sample:
complex.h :
#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
class Complex
{
public:
Complex(float Real, float Imaginary);
float real() const { return m_Real; };
private:
friend std::ostream& operator<<(std::ostream& o, const Complex& Cplx);
float m_Real;
float m_Imaginary;
};
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
#endif // COMPLEX_H
complex.cpp :
#include "complex.h"
Complex::Complex(float Real, float Imaginary) {
m_Real = Real;
m_Imaginary = Imaginary;
}
main.cpp :
#include "complex.h"
#include <iostream>
int main()
{
Complex Foo(3.4, 4.5);
std::cout << Foo << "\n";
return 0;
}
When compiling this code, I get the following error:
multiple definition of operator<<(std::ostream&, Complex const&)
I've found that making this function inline solves the problem, but I don't understand why. Why does the compiler complain about multiple definition? My header file is guarded (with #define COMPLEX_H).
And, if complaining about the operator<< function, why not complain about the public real() function, which is defined in the header as well?
And is there another solution besides using the inline keyword?
The problem is that the following piece of code is a definition, not a declaration:
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
You can either mark the function above and make it "inline" so that multiple translation units may define it:
inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
Or you can simply move the original definition of the function to the "complex.cpp" source file.
The compiler does not complain about "real()" because it is implicitly inlined (any member function whose body is given in the class declaration is interpreted as if it had been declared "inline"). The preprocessor guards prevent your header from being included more than once from a single translation unit ("*.cpp" source file"). However, both translation units see the same header file. Basically, the compiler compiles "main.cpp" to "main.o" (including any definitions given in the headers included by "main.cpp"), and the compiler separately compiles "complex.cpp" to "complex.o" (including any definitions given in the headers included by "complex.cpp"). Then the linker merges "main.o" and "complex.o" into a single binary file; it is at this point that the linker finds two definitions for a function of the same name. It is also at this point that the linker attempts to resolve external references (e.g. "main.o" refers to "Complex::Complex" but does not have a definition for that function... the linker locates the definition from "complex.o", and resolves that reference).
Move implementation to complex.cpp
Right now after including this file implementation is being compiled to every file.
Later during linking there's a obvious conflict because of duplicate implementations.
::real() is not reported because it's inline implicitly (implementation inside class definition)
I was having this problem, even after my source and header file were correct.
It turned out Eclipse was using stale artifacts from a previous (failed) build.
To fix, use Project > Clean then rebuild.
An alternative to designating a function definition in a header file as inline is to define it as static. This will also avoid the multiple definition error.

multiple definition in header file

Given this code sample:
complex.h :
#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
class Complex
{
public:
Complex(float Real, float Imaginary);
float real() const { return m_Real; };
private:
friend std::ostream& operator<<(std::ostream& o, const Complex& Cplx);
float m_Real;
float m_Imaginary;
};
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
#endif // COMPLEX_H
complex.cpp :
#include "complex.h"
Complex::Complex(float Real, float Imaginary) {
m_Real = Real;
m_Imaginary = Imaginary;
}
main.cpp :
#include "complex.h"
#include <iostream>
int main()
{
Complex Foo(3.4, 4.5);
std::cout << Foo << "\n";
return 0;
}
When compiling this code, I get the following error:
multiple definition of operator<<(std::ostream&, Complex const&)
I've found that making this function inline solves the problem, but I don't understand why. Why does the compiler complain about multiple definition? My header file is guarded (with #define COMPLEX_H).
And, if complaining about the operator<< function, why not complain about the public real() function, which is defined in the header as well?
And is there another solution besides using the inline keyword?
The problem is that the following piece of code is a definition, not a declaration:
std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
You can either mark the function above and make it "inline" so that multiple translation units may define it:
inline std::ostream& operator<<(std::ostream& o, const Complex& Cplx) {
return o << Cplx.m_Real << " i" << Cplx.m_Imaginary;
}
Or you can simply move the original definition of the function to the "complex.cpp" source file.
The compiler does not complain about "real()" because it is implicitly inlined (any member function whose body is given in the class declaration is interpreted as if it had been declared "inline"). The preprocessor guards prevent your header from being included more than once from a single translation unit ("*.cpp" source file"). However, both translation units see the same header file. Basically, the compiler compiles "main.cpp" to "main.o" (including any definitions given in the headers included by "main.cpp"), and the compiler separately compiles "complex.cpp" to "complex.o" (including any definitions given in the headers included by "complex.cpp"). Then the linker merges "main.o" and "complex.o" into a single binary file; it is at this point that the linker finds two definitions for a function of the same name. It is also at this point that the linker attempts to resolve external references (e.g. "main.o" refers to "Complex::Complex" but does not have a definition for that function... the linker locates the definition from "complex.o", and resolves that reference).
Move implementation to complex.cpp
Right now after including this file implementation is being compiled to every file.
Later during linking there's a obvious conflict because of duplicate implementations.
::real() is not reported because it's inline implicitly (implementation inside class definition)
I was having this problem, even after my source and header file were correct.
It turned out Eclipse was using stale artifacts from a previous (failed) build.
To fix, use Project > Clean then rebuild.
An alternative to designating a function definition in a header file as inline is to define it as static. This will also avoid the multiple definition error.