1

I have these two classes that need each other and inherited from the same class. Wehn I compile Seller.h, it compiles fine but when I compile Buyer.h I get errors from Seller.h.

So when i compile Buyer.h I get errors such as :

Seller.h:14:16: error: âBuyerâ has not been declared

  void addBuyer(Buyer*);

                ^
Seller.h:15:14: error: âBuyerâ was not declared in this scope
  std::vector<Buyer*>  getBuyers() const;

Seller.h:20:17: error: âOrderâ has not been declared
  void fillOrder(Order*);
             ^

They are #included but it still says out of scope.

#ifndef SELLER_H
#define SELLER_H
#include "Entity.h"
#include <string>
#include <vector>
#include "Inventory.h"
#include "Buyer.h"
#include "Order.h"
class Seller : public virtual Entity
{
public:
        Seller(const std::string &, const std::string &, double=0.0);
        virtual~Seller(){}
        void addBuyer(Buyer*);
        std::vector<Buyer*>  getBuyers() const;
        void setInventory(Inventory*);
        Inventory* getInventory() const;
        virtual void list() const override;
        virtual void step() override;
        void fillOrder(Order*);
private:
        Inventory* inv;
        std::vector <Buyer*> buyers;
};
#endif

Buyer.h

#ifndef BUYER_H
#define BUYER_H
#include <string>
#include "Entity.h"
#include <queue>
#include "Order.h"
#include "Seller.h"
class Buyer : public virtual Entity
{
public:
        Buyer(const std::string &, const std::string &, double =0.0 );
        virtual ~Buyer(){}
        void addSeller(Seller *);
        std::queue <Seller *> getSellers() const;
        void addOrder(Order *);
        std::queue <Order*>  getOrders() const;
        virtual void list() const override;
        virtual void step() override;

private:
        std::queue <Order*>  orders;
        std::queue <Seller*> sellers;
};
#endif
aschepler
  • 70,891
  • 9
  • 107
  • 161
user3582405
  • 21
  • 2
  • 3
  • 4
    You have a cyclic include dependency. That can't work. See http://stackoverflow.com/questions/625799/resolve-circular-dependencies-in-c – juanchopanza Apr 28 '14 at 17:48
  • I see it now. But how about the Order class? It's not really cyclic and I get an error for it as well – user3582405 Apr 28 '14 at 19:06

1 Answers1

2

You have a cyclic dependency between Seller and Buyer. This will never work because the compiler requires the declaration of Seller in order to compile Buyer... yet it also requires the declaration of Buyer to compile Seller.

You can instead forward declare your classes because all you actually use are pointers to these types. For example:

#ifndef SELLER_H
#define SELLER_H
#include "Entity.h"
#include <string>
#include <vector>
#include "Inventory.h"
#include "Order.h"

// forward declaration of Buyer
class Buyer;

class Seller : public virtual Entity
{
public:
        Seller(const std::string &, const std::string &, double=0.0);
        virtual ~Seller(){}
        void addBuyer(Buyer*);
        std::vector<Buyer*>  getBuyers() const;
        void setInventory(Inventory*);
        Inventory* getInventory() const;
        virtual void list() const override;
        virtual void step() override;
        void fillOrder(Order*);
private:
        Inventory* inv;
        std::vector <Buyer*> buyers;
};
#endif

If you had an instance of Buyer as a member of Seller (i.e., Buyer _buyer;), or if any method took/returned an instance of Buyer, you would be forced to change your structure. Since you don't have that problem, a forward declaration will suffice.


As an aside, and admitting that I am not privy to the structure of your program, it is usually a bad sign when one sees so many naked pointers being used in a C++ program. You can store instances. You can use safe pointers (shared_ptr and unique_ptr) depending on your ownership semantics.

For example, addBuyer can easily take a Buyer& instead of a pointer. Now you don't have to worry about invalid pointers. I'm assuming that you add these to your buyers vector... but how are you guaranteeing that these pointers remain valid for the lifetime of a Seller instance? You can't; you're at the mercy of whomever called addBuyer.

Why not just store a std::vector<Buyer> and take a reference in your add method? Is the cost of a copy so prohibitive as to warrant this design? If so, could you not use shared_ptr?

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • This is for a project and I was given some instructions, like using pointers and such. – user3582405 Apr 28 '14 at 19:02
  • I have a question about the Order class. Since my seller class also gives me an error for it. Why is it out of scope? I included it – user3582405 Apr 28 '14 at 19:03
  • @user3582405: Well, you'd have to post your `Order` declaration, but could it be the same problem? Does `Order` use `Seller`? – Ed S. Apr 28 '14 at 20:27
  • No, it's just a helping class to make objects from. But both seller and buyer use order. Is it that any class that they both share produce that error? – user3582405 Apr 28 '14 at 20:31
  • Are you certain that error persists after fixing the problem I described? If it does you'll need to show us that header file. – Ed S. Apr 28 '14 at 20:44