1

I have the SuperClass called Transaction, it has methods:

  • Type
  • Guid
  • Customer

then the subclass called Order has these methods:

  • item
  • quantity
  • cost ...

so Order inherits from Transaction.

My problem is that there can be multiple types of transactions... Orders, Payment, etc.

Therefore i hold every type of transaction in the array like this:

Transaction trans[100];
trans[0] = Order order(val,val,val);
trans[1] = Order order(val,val,val);
trans[2] = Order order(val,val,val);
...

But now when i call trans[3].Get_item(); i get error that Transaction class has no method Get_item, yes it doesn't but what it's holding has.

I have tried making array an array of pointers and accessing using -> operator. But the problem persists.

Real Code ::::::

vector<Transaction *> trans;
....
Order order(words[0], words[1], words[2], words[3], words[4], words[5]);
trans.push_back(&order);
....
trans[i]->Getitem(); //error here.
Muhammad Umer
  • 17,263
  • 19
  • 97
  • 168
  • 1
    See also: https://en.wikipedia.org/wiki/Object_slicing , http://stackoverflow.com/questions/274626/what-is-object-slicing – Igor Tandetnik Sep 27 '15 at 18:45
  • How do you know that `trans[i]` points to an `Order` (and not, say, a `Payment`), and that `GetItem()` call on it makes sense? If all transactions in the vector are in fact orders, then store a vector of `Order*`. If not all are, then it's back to "how do you plan to know which are which"? – Igor Tandetnik Sep 27 '15 at 18:49
  • Actually i looked again, And i Am storing type in the Transaction – Muhammad Umer Sep 27 '15 at 18:51

1 Answers1

4

An array like Transaction trans[100]; can't hold subclasses of Transaction, only Transaction itself. If you want an array to hold arbitrary Transaction child classes, make an array of pointers (raw or not doesn't matter). Example with a vector and raw pointers:

std::vector<Transaction *> t;  
t.push_bask(new Transaction()); //insert constructor params if necessary params 
t.push_bask(new Order());  
t[0]->getType();
t[1]->getType();
...
//and don't forget delete, or use smart pointers.

If you additionally need to access methods not available at all in the parent, the compiler needs to know the actual type, ie. it expects you to make an appropriate cast first. If you can't say what type it is, you can't call the method.

((Order*)t[1])->getItem(); //you can do that because you know [1] is a Order  

//but this is wrong and leads to UB:
((Order*)t[0])->getItem();  //wrong!

In some (not all) situations, dynamic_cast can help to test for some type.

deviantfan
  • 11,268
  • 3
  • 32
  • 49
  • can you post some example code...i did make mine to pointers, also it was vector. ` vector trans;` then `trans[i]->Getitem()` doesn't work – Muhammad Umer Sep 27 '15 at 18:46
  • i store type in Trasnaction so i should be able to use Order casting – Muhammad Umer Sep 27 '15 at 18:54
  • If you can find out with getType if it's a Order then it's ok, problem solved. – deviantfan Sep 27 '15 at 18:55
  • 1
    Btw., your last code sample in the question has a pointer to a local variable which may be gone before the vector is. Careful with that. – deviantfan Sep 27 '15 at 18:55
  • 1
    @MuhammadUmer If you insert a Order in the Transaction vector (without pointers), the Order object is copied with the copy constructor of Transaction => What's in the vector is a pure Transaction, nothing else. (And with pointers, only the pointer address is copied) – deviantfan Sep 27 '15 at 18:57
  • thanks for the warning that would have been another problem. – Muhammad Umer Sep 27 '15 at 19:00