Multiple Definitions error

Nov 20, 2008 at 1:41am
So I get this nasty multiple definitions error when I compile my program with g++. The program uses two classes, cbt (complete binary tree), and node which are both defined in tree.h


from the terminal:
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
make
g++ -c -Wall tree.cpp
g++ -g -Wall -o cbtfun cbtfun.cpp tree.o
tree.o: In function `cbt::distance(Node*, Node*)':
tree.cpp:(.text+0x0): multiple definition of `cbt::distance(Node*, Node*)'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:81: first defined here
tree.o: In function `cbt::findDistances()':
tree.cpp:(.text+0x8a): multiple definition of `cbt::findDistances()'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:63: first defined here
tree.o: In function `log2(unsigned int)':
tree.cpp:(.text+0xfa): multiple definition of `log2(unsigned int)'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:141: first defined here
tree.o: In function `cbt::deleteSubtree(Node*&)':
tree.cpp:(.text+0x1dc): multiple definition of `cbt::deleteSubtree(Node*&)'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:119: first defined here
tree.o: In function `cbt::~cbt()':
tree.cpp:(.text+0x232): multiple definition of `cbt::~cbt()'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:134: first defined here
tree.o: In function `cbt::~cbt()':
tree.cpp:(.text+0x26e): multiple definition of `cbt::~cbt()'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:134: first defined here
tree.o: In function `cbt::~cbt()':
tree.cpp:(.text+0x2aa): multiple definition of `cbt::~cbt()'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:134: first defined here
tree.o: In function `cbt::preOrderShow(Node*) const':
tree.cpp:(.text+0x2e6): multiple definition of `cbt::preOrderShow(Node*) const'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:102: first defined here
tree.o: In function `cbt::preOrderShow() const':
tree.cpp:(.text+0x344): multiple definition of `cbt::preOrderShow() const'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:113: first defined here
tree.o: In function `cbt::cbt(int)':
tree.cpp:(.text+0x362): multiple definition of `cbt::cbt(int)'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:17: first defined here
tree.o: In function `cbt::cbt(int)':
tree.cpp:(.text+0x5c2): multiple definition of `cbt::cbt(int)'
/tmp/ccZYPpvM.o:/fs/home1/student/b/bfurlong/workspace/cbtfun/tree.cpp:17: first defined here


tree.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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef TREE_H
#define TREE_H

    class cbt; //forward declaration

    class Node
    {
    public:
        Node( ) : parent(NULL), left(NULL), right(NULL), next(NULL){}
        Node(int theData, Node* parentLink, Node* leftLink, Node* rightLink, Node* nextLink)
            : data(theData), parent(parentLink), left(leftLink), right(rightLink), next(nextLink){}
        friend class cbt;
        int data;
        int level;
        Node *parent;
        Node *left;
        Node *right;
        Node *next;
    };









    class cbt
    {
    public:
        cbt( ) : root(NULL){}
        cbt(int numberOfNodes);
        void findDistances();
        void deleteSubtree(Node*& subTreeRoot);
        virtual ~cbt( );
        int distance(Node* self, Node* relative);
        void preOrderShow( ) const;
        void preOrderShow(Node* subTreeRoot) const;
        Node *root;
    };


#endif 


tree.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
#include <iostream>
#include <cstddef>
#include <cstdlib>
#include "tree.h"
using namespace std;
int log2(unsigned int n);

//Preconditions: numberOfNodes >= 0
//Postconditions: constructs CBT with data = -1 and level = 0 for root, 1 for next level, etc.
cbt::cbt(int numberOfNodes) // MULT DEF ERROR
{
...
}

// PREC: Valid CBT
// POSTC: Valid CBT has its total distances in data field of its nodes.
void cbt::findDistances()  // MULT DEFINITION ERROR
{
...
}

// PREC: takes two nodes of a valid CBT
// POSTC: returns the distance between the two nodes
int cbt::distance(Node* self, Node* relative)
{
...
}

void cbt::preOrderShow(Node* subTreeRoot) const // MULT DEF ERROR
{
...
}


void cbt::preOrderShow( ) const  // MULT DEF ERROR
{
...
}


void cbt::deleteSubtree(Node*& subTreeRoot) // MULT DEF ERROR
{
...
}


cbt::~cbt( ) // ERROR HERE
{
...
}

// precondition: takes any integer
// postcondition: gives floored binary log of the integer.  returns -1 if integer is 0.
int log2(unsigned int n) { // ERROR here
...
}


I have no idea what to do to fix this so please help...
Nov 20, 2008 at 2:03am
It's gotta be that forward declaration. You declare class cbt twice. Since all of your Node methods are public, do you need cbt to be a friend class? If not then you can get rid of that declaration at the top. If you do, you might try putting the node and the cbt stuff in separate headers which include each other... Hopefully that works
Nov 20, 2008 at 2:51am
No, mutual inclusion only leads to compiler errors.
I've never actually encountered this problem myself, but I once asked my favorite teacher about how to solve such a problem and his answer was "derive one class from the other".
Alternatively, you could merge both classes into one and add a type value to keep the methods from messing up the data. It would also be advisable to make the data private, just in case.
Nov 20, 2008 at 4:36am
Inheritance doesn't really make sense in this case because the node doesn't inherit properties of the tree.

I think maybe the correct solution would be to nest the Node class inside the tree class.

like:
1
2
3
4
5
6
7
8
class cbt{

    class Node {
         // Node stuff....
    };

    // cbt stuff...
};
Last edited on Nov 20, 2008 at 4:36am
Nov 20, 2008 at 1:07pm
Ok, this is a link error. Changing code isn't going to do much. The posted code does not look like it should generate a link error, however the source for cbtfun.cpp is not posted.
What does cbtfun.cpp #include? It's not including tree.cpp is it?
Nov 20, 2008 at 5:12pm
header for cbtfun.cpp

1
2
3
#include <iostream>
#include "tree.h"
#include "tree.cpp" 
Nov 20, 2008 at 5:55pm
Yup, remove #include "tree.cpp" and it will work.

EDIT: never #include .cpp files. Only header files.
Last edited on Nov 20, 2008 at 5:56pm
Topic archived. No new replies allowed.