class person { protected: char *name, *ident, *address, *phone; public: person(char *n, char *i, char *a, char *p); char *get_name(void); char *get_ident(void); char *get_address(void); char *get_phone(void); void set_address(char *a); void set_phone(char *p); void print(void); }; class customer: public person { protected: int rating, balance; etc etc etc }; class employee: public person { protected: char *jobtitle, *supervisor; int salary; etc etc etc }; class family: public person { protected: char *employee; etc etc etc }; class stockholder: public person { protected: int numshares; etc etc etc }; |
{ person P1("jim","K192A","123 Ant St","532-5841"); person P2("Meg","W738R","456 Bat St","737-1092"); customer C1("Bat","C71828-54","222 Cat St","123-8765",60,0); // it is OK to do this assignment P2=C1; // because all operations allowed on P2 are meaningful for a customer P2.set_address("987 Dog St"); P2.print(); x=P2.get_name(); // all of those are OK because even though P2 contains a customer, those // methods must exist for all customers // On the other hand, it is NOT OK to do this assignment C1=P1; // because some things we might do with a customer will be meaningless C1.set_rating(35); x=C1.get_balance(); // those two statements are allowed because C1 was declared as a customer // and customers have set_rating and get_balance methods. However, the // variable C1 actually contains a person object, and persons do not have // set_rating or get_balance methods, or even rating and balance members. |
{ person *P1=new person("jim","K192A","123 Ant St","532-5841"); person *P2; customer *C1=new customer("Bat","C71828-54","222 Cat St","123-8765",60,0); // it is OK to do this assignment P2=C1; // because all operations allowed on P2 are meaningful for a customer P2->set_address("987 Dog St"); P2->print(); x=P2->get_name(); // all of those are OK because even though P2 contains a customer, those // methods must exist for all customers // On the other hand, it is NOT OK to do this assignment C1=P1; // because some things we might do with a customer will be meaningless C1->set_rating(35); x=C1->get_balance(); // those two statements are allowed because C1 was declared as a customer // and customers have set_rating and get_balance methods. However, the // variable C1 actually contains a person object, and persons do not have // set_rating or get_balance methods, or even rating and balance members. |
When one class (A) is derived from (or inherits) another class (B), it is guaranteed that an A object can do anything that a B object can do, therefore it is permitted to store pointers to A objects in variables declared as pointers to B. |
{ customer *custs[1000]; employee *emps[1000]; family *empfam[1000]; stockholder *owners[100]; ... custs[33]=new customer("...","...",...); ... emps[175]=new employee("...","...",...); ... } |
{ person *everyone[10000]; ... everyone[33]=new customer("...","...",...); ... everyone[175]=new employee("...","...",...); ... } |
person *find(char *nm) { int i; for (i=0; i |
person *x=find("jimmy"); // that's OK, but x is only a pointer-to-person. If "jimmy" // happens to be a customer, we can't use x to access his // credit rating or balance. customer *x=find("jimmy"); // that is not OK, because polymorphism only works in one direction. // find returns a person-pointer, which can't be stored in a customer-pointer variable. customer *x=(customer *)find("jimmy"); // that would work. type casting is very useful in // situations like this |
class person { protected: char tag; char *name, *ident, *address, *phone; public: person(char *n, char *i, char *a, char *p) { tag='X'; everything else as before } all other methods as before }; class customer: public person { protected: int rating, balance; public customer(char *n, char *i, char *a, char *p, int r, int b): person(n,i,a,p) { tag='C'; rating=r; balance=b; } all other methods as before }; etc etc etc |
{ person *temp; customer *cust; ... temp=find("jimmy"); if (temp->tag=='C') cust=(customer *)temp; else { cust=NULL; print an error message } ... |