2

I am getting an undefined reference and I have no clue why, everything looks properly declared and defined and linked, but obviously there is something wrong.

Error:

I am getting undefined reference to UserOrder::add(User&, Order&) called in Order::Order(UserOrder& [...])

order.h:

#include "user-order.h"

class Order {
public:
    Order(UserOrder& [...], User&, [...]);
    [...]
};

order.cpp

Order::Order(UserOrder& u_o [...], User& u, [...]) {
    [...]
    u_o.add(u, *this); // here is the undefined reference
    [...]
}

user-order.h:

#include "user.h"
#include "order.h"
class Order;

class UserOrder {
public:
    [...]
    typedef std::set<Order*> Orders;
    void add(User&, Order&);
    [...]   
private:
    std::map<User*, Orders> orders;
    std::map<Order*, User*> users;
};

user.cpp

UserOrder::add(User& u, Order& o) {
    orders[&u].insert(&o);
    users.insert(make_pair(&o, &u)); 
}

Why the heck am I getting undefined refference for add?

Axel
  • 13,939
  • 5
  • 50
  • 79
dabadaba
  • 9,064
  • 21
  • 85
  • 155
  • 1
    How do you build? And could you give us a [minimal complete example](http://www.sscce.org/)? – Beta May 14 '14 at 16:10
  • I think you're crossing references. UserOrder imports Order and Order imports UserOrder, so it could be the issue. – Julián Chamalé May 14 '14 at 16:12
  • `order.h` and `user-order.h` include each other and you don't seem to have include guards in either one. Try adding them, and also see if you can avoid the circular includes. – kevintodisco May 14 '14 at 16:12
  • 2
    @Beta was right. The problem is I wasn't counting on `user-order.cpp` when building. – dabadaba May 14 '14 at 16:13
  • When you include the "user-order.h" file, that one tries to include "order.h" again. Because of that when you get to the the u_o.add part, the compiler doesn't know how to handle it since it hasn't seen the declaration of the UserOrder class yet. – Veritas May 14 '14 at 16:14
  • @ktodisco: If that had been the problem, it wouldn't have compiled. – Beta May 14 '14 at 16:23
  • @Beta I'm well aware, but that doesn't make it advice that shouldn't be taken. – kevintodisco May 14 '14 at 16:25
  • 1
    What is your compiling options? Have you added .cpp files to your makefile or project? – masoud May 14 '14 at 16:26
  • there is also a problem in `UserOrder::add` method in line `orders[&u].insert(&o);` - this shouldn't compile as `[]` is already referencing the item in `orders` map - so the line should be `orders[&u] = &o;`. – NirMH May 21 '14 at 11:02

1 Answers1

1

You have a cyclic #include scenario.

pay attention...

order.h

#include "user-order.h"

and

user-order.h

#include "order.h"

so the compiler can't know the definition of all your types during the compilation process.

You'll have to redesign your class diagram. As you've have not posted any additional code except from partial method prototypes, i can only suggest you may turn the Order class into a polymorphic base and derive UserOrder from it.

Of course your program might need additional re-factor operations.

EDIT - you can find useful info about how to resolve the circular dependency in the following Resolve circular dependencies in c++ Stack Overflow post

Community
  • 1
  • 1
NirMH
  • 4,769
  • 3
  • 44
  • 69