#include file -> Multiple definitions

I've created a Fraction class and it works fine.

Then I was trying to move it to a diferent file, so that I could use whenever I needed it.

This is the class file, "fraction.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
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
#include <iostream>
using namespace std;

class Fraction
{
    private:
        int num,den;

    public:
        //Constructors:
        Fraction(){num=0;den=0;normalize();}
        Fraction(const int &n, const int &d){set(n,d);}
        Fraction(const int &n){set(n,1);}

        //Copy-Constructor:
        Fraction(Fraction const &src){num=src.num;den=src.den;}

        void set(const int &n, const int &d){num=n;den=d;normalize();}  //Inline, because it's declared inside the class declaration
        int get_n() const {return num;}//const here makes sure that no changes are made to data members
        int get_d() const {return den;}//or functions that do so are called.

        //Operations:
        Fraction add(const Fraction &other); //Pass by reference is faster, as no copies are made
        Fraction sub(Fraction other);
        Fraction mult(const Fraction &other);
        Fraction div(const Fraction &other);

        //Operator Overloading:
        Fraction operator+(const Fraction &other){return add(other);}
        Fraction operator-(const Fraction &other){return sub(other);}
        Fraction operator*(const Fraction &other){return mult(other);}
        Fraction operator/(const Fraction &other){return div(other);}

        bool operator==(const Fraction &other){return (num==other.num && den==other.den);} //this expression evaluates to 1 if both are true or 0 if one or both are not.
        bool operator>(const Fraction &other){return (num*other.den>den*other.num);}
        bool operator<(const Fraction &other){return !(*this>other);}

        //Supporting other operand types with friend functions
        //Friend Functions are not member functions but can
        //access data members:
        friend Fraction operator+(const int &n, const Fraction &f1);
        friend Fraction operator-(const int &n, const Fraction &f1);
        friend Fraction operator*(const int &n, const Fraction &f1);
        friend Fraction operator/(const int &n, const Fraction &f1);
        friend ostream &operator<<(ostream &os, const Fraction &f1);
        friend bool operator==(const int &n, const Fraction &f1);
        friend bool operator>(const int &n, const Fraction &f1);
        friend bool operator<(const int &n, const Fraction &f1);



    private:
        void normalize();
        int gcf(const int &a, const int &b);
        int lcm(const int &a, const int &b);
};

...

//Function definitions...

...


my main looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "fraction.cpp"

int main()
{
    Fraction a(3,3);
    Fraction b(2,4);
    Fraction c=1/a;

    cout<<c<<endl<<a<<endl;
    cout<<(int)(1==a);

    return 0;
}


Code::Blocks doesn't compile and spits this out:
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
o\Cpp\my_library\fraction.cpp|11|multiple definition of `Fraction::normalize()'|
o\Cpp\my_library\fraction.cpp|59|first defined here|
o\Cpp\my_library\fraction.cpp|78|multiple definition of `Fraction::gcf(int const&, int const&)'|
o\Cpp\my_library\fraction.cpp|78|first defined here|
o\Cpp\my_library\fraction.cpp|91|multiple definition of `Fraction::lcm(int const&, int const&)'|
o\Cpp\my_library\fraction.cpp|91|first defined here|
o\Cpp\my_library\fraction.cpp|96|multiple definition of `Fraction::add(Fraction const&)'|
o\Cpp\my_library\fraction.cpp|96|first defined here|
o\Cpp\my_library\fraction.cpp|108|multiple definition of `Fraction::mult(Fraction const&)'|
o\Cpp\my_library\fraction.cpp|108|first defined here|
o\Cpp\my_library\fraction.cpp|117|multiple definition of `Fraction::sub(Fraction)'|
o\Cpp\my_library\fraction.cpp|117|first defined here|
o\Cpp\my_library\fraction.cpp|123|multiple definition of `Fraction::div(Fraction const&)'|
o\Cpp\my_library\fraction.cpp|123|first defined here|
obj\Debug\fraction.o||In function `ZplRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|134|multiple definition of `operator+(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|134|first defined here|
obj\Debug\fraction.o||In function `ZmiRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|138|multiple definition of `operator-(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|138|first defined here|
obj\Debug\fraction.o||In function `ZmlRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|143|multiple definition of `operator*(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|143|first defined here|
obj\Debug\fraction.o||In function `ZdvRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|148|multiple definition of `operator/(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|148|first defined here|
obj\Debug\fraction.o||In function `ZlsRSoRK8Fraction':|
o\Cpp\my_library\fraction.cpp|153|multiple definition of `operator<<(std::ostream&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|153|first defined here|
obj\Debug\fraction.o||In function `ZeqRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|159|multiple definition of `operator==(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|159|first defined here|
obj\Debug\fraction.o||In function `ZgtRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|164|multiple definition of `operator>(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|164|first defined here|
obj\Debug\fraction.o||In function `ZltRKiRK8Fraction':|
o\Cpp\my_library\fraction.cpp|169|multiple definition of `operator<(int const&, Fraction const&)'|
o\Cpp\my_library\fraction.cpp|169|first defined here|
||=== Build finished: 30 errors, 0 warnings ===|
 


How can I have multiple definitions if they're defined only once?


EDIT: If I compile everything in main.cpp, it works fine...
Last edited on
closed account (iLUjLyTq)
Change the filename from 'fraction.cpp' to 'fraction.h' and leave the declarations there as they are. Next create a 'fraction.cpp' file, #include "fraction.h" in it and define the class methods there. Then #include "fraction.h" in the main file.
Last edited on
Worked, thank's.

Although I have to include:

#include <iostream>
using namespace std;

in the fraction.h as well even though I have my main like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

#include "fraction.h"



int main()
{
    Fraction a(3,3);
    Fraction b(2,4);
    Fraction c=1/a;

    cout<<c<<endl<<a<<endl;
    cout<<(int)(1==a);

    return 0;
}


This way aren't I compilling the iostream libraries twice?
closed account (iLUjLyTq)
You may remove iostream and std namespace from main as they're already included in your header.
I have a my_library.h set up this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

//Fraction class support
#include "fraction.h"



//Get an int or double number from cin.
int get_number(const int &def);
double get_number(const double &def);

//Swaps the values of two variables of the same type:
void swap(int &a, int &b);
void swap(double &a, double &b);
void swap(char *&a, char *&b);


Calls to iostream are originated before the fraction.h call, however I need to include a call to iostream in fraction.h because if I don't it will complain.

http://www.cplusplus.com/doc/tutorial/preprocessor/

|
---> "When the preprocessor finds an #include directive it replaces it by the entire content of the specified file."

Being this the case I should have to call iostream in my_library.h, right?

(Main.cpp calls my_library.h)
closed account (iLUjLyTq)
Yes, you're right.
closed account (S6k9GNh0)
?? If the header doesn't use any types declared in iostream, there is no reason to use iostream in the header.

If the implementation does, then include the header in the implementation. This helps with abstraction and minimizes problems for the user of the library.

EDIT: Also, the official header for C++ strings is "string", not "string.h". To properly use C string functionality, use "cstring" with no extension. Same for stdlib e.g. "cstdlib". I also do not see any functions or types from the headers included in the given file therefor, it's generally bad practice to include them in that manner.
Last edited on
+1 computerquip
both get_number use cin.getline and strlen, that's why I include them.

The book I'm reading now ("C++ without fear") still refers to stdlib.h and string.h instead of cstdlib and cstring, now I now that those are what I should use. Thanks
closed account (S6k9GNh0)
Look at this example, compiled as a type of library:

Example.h
1
2
3
4
5
6
7
8
#ifndef EXAMPLE_H
#define EXAMPLE_H

//Nice and minimal, just how we like it.
void print_number(int);
int get_number();

#endif 


Example.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
#include <iostream>
#include <string>
#include <sstream>

void print_number(int num)
{
   std::cout << num << std::endl;
}

int get_number()
{
   std::string input;
   std::getline(cin, input);
   
   std::stringstream ss(input);
   int output;
   if (!(ss >> output)) //if conversion failed
   {
      std::cout << "Conversion failed! Output will be 0." << std::endl;
      output = 0;
   }

   return output;
}


Notice where the headers are placed. In a libraries case, including things that are not of the interface can cause the user of the library to have larger compile times or even cause more problems than are needed.

Also, if "C++ Without Fear" does not cover the standards in *at least* C++03, then I would recommend getting a more modern book. C++ is already past two major revisions since C++98.
Last edited on
I heard that a new standard is coming out, so I'm waiting to buy a new book.

Thank's for the input,

Hugo Ribeira
Topic archived. No new replies allowed.