I have a problem trying to access functions from the derived classes that are not virtual functions. So in my code I can not use the add(sting s) or setManifest(string s) calls. Am I missing something?
int main()
{
ShippingContainer *ar[6] =
{
new ManualShippingContainer(),
new ManualShippingContainer(),
new ManualShippingContainer(),
new RFIDShippingContainer(),
new RFIDShippingContainer(),
new RFIDShippingContainer()
};
ar[3]->setID(20);
ar[3]->add("crate of apple");
ar[3]->add("crate of apple");
ar[3]->add("crate of apple");
ar[3]->add("crate of apple");
ar[3]->add("crate of oranges");
ar[3]->add("crate of oranges");
ar[3]->add("crate of oranges");
ar[3]->add("crate of bananas");
ar[4]->setID(25);
ar[4]->add("crate of apples");
ar[5]->setID(30);
ar[5]->add("crate of oranges");
ar[5]->add("crate of oranges");
ar[5]->add("crate of apples");
I have a problem trying to access functions from the derived classes that are not virtual functions.
If you have a ShippingContainer pointer (as is the case with your 'ar' array), you cannot call functions of ManualShippingContainer. After all, there is no guarantee that the ShippingContainer pointer actually points to a ManualShippingContainer object! Also, there is no way for the compiler to know this is your intent.
To solve this problem, you either need to:
1) design your class hierarchy in a way which virtual functions can be utilized so that you don't have this problem
2) downcast to the derived class, either with dynamic_cast (safe), or with static_cast (not as safe, but quicker).
Example:
1 2 3 4 5 6 7 8 9 10
// error.. setManifest not a member of ShippingContainer
ar[0]->setManifest("foo");
// ok, but unsafe
static_cast<ManualShippingContainer*>(ar[0])->setManifest("foo");
// okay and safe
ManualShippingContainer* p = dynamic_cast<ManualShippingContainer*>(ar[0]);
if(p)
p->setManifest("foo");
dynamic_cast does a runtime check to ensure that the cast is legit (ie, the pointer actually points to a ManualShippingContainer object). If the cast is bad, dynamic_cast will return a null pointer.
static_cast does no such runtime check, and if the cast is bad you will call the funciton with a corrupt this pointer which could lead to all kinds of disasterous consequences that are VERY hard to find when debugging. Only use static_cast for downcasting when you are 100% absolutely positive you're casting properly.
If you create a B and assign it to a pointer to A, like this A *p=new B;, p cannot call B::f(), it will always call A::f(). You could override this by casting p to a B *, but that's no very nice. Instead you make A::f() virtual, so that derived classes can override it: