multiple definition of operator<<(std::ostream&, Shape const&)

Shape<-Triangle<-IsoTriangle
Here shape and triangle are abstract classes.
When I compile
1
2
        IsoTriangle rect(5,"DUMBA DUMBA");
	cout << rect << endl;

I get multiple definition of `operator<<(std::ostream&, Shape const&)`

Shape.h
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
#ifndef SHAPE_H
#define SHAPE_H
#include<string>
#include<vector>
#include<iostream>
#include<typeinfo>
using namespace std;



class Shape {
private:
	//Some Members
public:

	//Some Members
};
ostream& operator<<(ostream& os, const Shape& obj) {
  //Some code
  return os;
}

ostream& operator<<(ostream& os,  const vector< vector<char> >& grid) {
  //Some code
  return os;
}

#endif


Triangle.h
1
2
3
4
5
6
7
8
#ifndef TRIANGLE_H
#define TRIANGLE_H
#include"Shape.h"

class Triangle: public Shape{
};

#endif 


IsoTriangle.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef IsoTriangle_H
#define IsoTriangle_H
#include"Triangle.h"
#include<typeinfo>
#include<string>
#include <cmath>


class IsoTriangle : public Triangle {
//Some definitions but no operator<< definition
};



#endif // !IsoTriangle_H


IsoTriangle.cpp
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
#include "IsoTriangle.h"
#include <iostream>

IsoTriangle::IsoTriangle(int base) {

}

IsoTriangle::IsoTriangle(int base, string desc_name) {

}

IsoTriangle::~IsoTriangle() {

}



int main()
{
  IsoTriangle rect(5);

  cout << rect << endl;

}


Last edited on
I can't see an operator<< being defined anywhere in your code.
@Peter87 I changed the code have a look
Looks like Cubbi guessed correctly.

http://www.cplusplus.com/forum/beginner/219304/#msg1010844

In general, you should avoid defining non-template functions inside of header files, but when you find it appropriate, you should give them external linkage via the inline specifier. (In the case of member methods or friend functions, defining them inside the class is sufficient to make your intent clear to your compiler.)
How does the inline specifier actually help in this case? If I omit inline how is compiler finding multiple definitions and how its not finding multiple definitions when I use Inline. Also is there a way to attach files here?
Imagine that there are two source files and one header file:

header.hxx
 
int f() { return 42; }

source-a.cxx
 
# include "header.hxx" 

source-b.cxx
 
# include "header.hxx" 


After preprocessing, the two translation units (i.e., source-a.cxx and source-b.cxx) contain
source-a.cxx
 
int f() { return 42; }

And
source-b.cxx
 
int f() { return 42; }

There's a duplicate definition, and this causes the linker to complain. This happens even if there is an include guard in the header file, because preprocessing happens separately for each TU (translation unit).

The purpose of the inline specifier is to allow multiple identical definitions, one per TU. See:
http://en.cppreference.com/w/cpp/language/inline
Last edited on
Is there any way to tell compiler that if an header is included once dont load it again?
Yes, but only per translation unit. Wrap the header contents in an include guard:

your-header.hxx
1
2
3
4
5
6
# if ! defined YOUR_HEADER_INCLUDED
# define YOUR_HEADER_INCLUDED

// header contents here 

# endif  

Where the macro name YOUR_HEADER_INCLUDED is some unique symbol.

But this solves a different problem, where the same definition is included twice in the same translation unit:
header.hxx
 
struct A {};

source.cxx
1
2
# include "header.hxx"
# include "header.hxx" 

After preprocessing, the single translation unit source.cxx would contain
1
2
struct A {};
struct A {};

Which violates the One Definition Rule.

One solution is to only include the header once, but it's often the case where the same header is included indirectly through many other header files. In these cases, it can be extremely difficult to identify and resolve the source of a multiple inclusion without tearing your hair out. So a header guard can (should) be used:
header.hxx
1
2
3
4
# if ! defined HEADER_HXX_INCLUDED
# define HEADER_HXX_INCLUDED
struct A {}; 
# endif 

source.cxx
1
2
# include "header.hxx"
# include "header.hxx" 

The translation unit (source.cxx) is semantically equivalent to the following:
1
2
3
4
5
6
7
8
# if ! defined HEADER_HXX_INCLUDED
# define HEADER_HXX_INCLUDED
struct A {}; 
# endif
# if ! defined HEADER_HXX_INCLUDED
# define HEADER_HXX_INCLUDED
struct A {}; 
# endif 

Which hopefully makes it apparent why only one definition of A{} remains after preprocessing.

While it is good practice to use include guards in every header file, this wouldn't solve your problem because each translation unit is preprocessed separately, leading to the problem illustrated in the post above.

See also:
http://en.cppreference.com/w/cpp/preprocessor/include
https://en.wikipedia.org/wiki/Include_guard
Last edited on
@mbozzi, I actually had header guards but still was getting multiple definitions. But making it inline however solved the problem.
The excutable has one copy of the code of each function and the other parts of the program that use a function have code that jumps to the function's code and back.

Inlined function does not exists. Its code is repeated in each place where it is used and there is no "function call" code. (Compiler can judge that a function is too complex to inline, but apparently compiler and linker are able to make believe.)


Anyway, a recommended way is to move the implementations into a source file:

Shape.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef SHAPE_H
#define SHAPE_H

#include<string>
#include<vector>
#include<iostream>
#include<typeinfo>

class Shape {
private:
	//Some Members
public:
	//Some Members
};

std::ostream& operator<<( std::ostream& os, const Shape& obj );

std::ostream& operator<<( std::ostream& os,
                          const std::vector< std::vector<char> >& grid );

#endif 


Shape.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<vector>
#include<iostream>
#include "shape.h"

std::ostream& operator<<( std::ostream& os, const Shape& obj )
{
  //Some code
  return os;
}

std::ostream& operator<<( std::ostream& os,
                          const std::vector< std::vector<char> >& grid )
{
  //Some code
  return os;
}

Putting the implementation in a source file has the advantage of faster compilation.
Topic archived. No new replies allowed.