array of one class in another, both children of same abstract class

Hello,

Suppose I sell thingy's online. I accept orders of one or 10 thingy's. If the order is for one thingy, I use the postal service to ship the order. If the order is for a box of thingy's, I need to ship via UPS. I want to keep track of all my orders in one place, but I need to use different shipment methods depending on the size of the order.

I want to be able to store all my orders in an array of type Order, so Order is my parent class. Thingy is a child of Order. Box (of thingy's) is also a child of Order, but Box contains 10 Thingy's (in the form of an array). I'm attempting to use Order as an abstract class with a virtual "ship" method, so the shipment method can change based on what child type is being used in the array.

I am not sure how to handle this particular arrangement of class relationships, and cannot find an example anywhere. The code below is a skeleton of what I've tried, but it won't compile. I get an error about the array "boxOfThingy" being abstract. Do I need something special in my constructors? Is this even possible? Is there a better way to do this?

Many thanks!

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
class Order
{
  public:
    virtual void ship() = 0 ;
    ~Order() ;
} ;

class Thingy : public Order
{
  private:
   ...
  public:
   ...
   void ship() ;
   Thingy() ;
} ;

class Box : public Order
{
  private:
   ...
   Thingy boxOfThingy[10] ;
  public:
   ...
   void ship() ;
   Box() ;
} ;
I would question if inheritance is the right solution to this problem. While you could tweak it to work, it doesn't really make a lot of sense.

Inheritance implies an "is a" relationship. You might have an order for a Thingy or for a Box, but does that mean that a box is an order?

Especially since Box has an array of thingys, does this mean your box is an order of 10 orders?

And then can you have an order of multiple items? What if a customer orders 3 Thingys and a Box? Would you have to create 4 different orders?


The approach I would take would be to have a different structure using "has a" relationships to tie the orders with what they're ordering, rather than "is a" relationships.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Order
{
  ...
  list<Commodity*> items;  // item(s) being ordered ("has a" relationship)
};

class Commodity
{
// abstract base class for items that can be ordered
};

class Thingy : public Commodity  // "is a" relationship -- a Thingy is a Commodity
{
};

class Box : public Commodity
{
};


Then if you want different commodities to be shipped differently, you can have the commodity itself return the desired type of order:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Commodity
{
  virtual Order MakeOrder()
  {
    // make a generic order
  }
};

//-------------------
class Thingy : public Commodity
{
  virtual Order MakeOrder()
  {
    // make an order specific to shipping 1 Thingy
    //  (use Postal Service or whatever)
  }
};



As for your error.... it saying thingy being abstract typically means that there is a pure virtual function in Order that you did not give a body for in Thingy.
Topic archived. No new replies allowed.