// Bank account objects in pure C #include #include // tag values (dynamic type information) for account structures: #define BASE 0 #define SAVINGS 1 #define CHECKING 2 typedef struct accstruct * account; struct accstruct { int balance; int tag; // 0 for generic account, 1 for savings, 2 for checking union // extra union contains bonus or fee { int bonus; // for savings account int fee; // for checking account } extra; // either extra->bonus or extra->fee exists }; // constructor account newaccount(int bal) { account A = (account)malloc(sizeof(struct accstruct)); A->balance = bal; // set init balance return A; } // destructor void freeaccount(account A) { free(A); } void deposit0(account A, int amt) { A->balance += amt; } void withdraw0(account A, int amt) { if (amt<=A->balance) A->balance -= amt; } int inquiry(account A) { return A->balance; } int moremoney(account A, account B) { return (A->balance > B->balance); } ///////////////////////// void bless(account A, int dtype) // "bless" borrowed from Perl { A->tag = dtype; } // "subclass" constructors account newsavings(int bal, int bn) { account A = newaccount(bal); // calls "superclass" constructor A->extra.bonus = bn; // sets bonus bless(A,SAVINGS); // thou shall be a savings account return A; // thou are so blessed. } account newchecking(int bal, int fee) { account A = newaccount(bal); // calls "superclass" constructor A->extra.fee = fee; // sets bonus bless(A,CHECKING); return A; } // new methods that should "override" old ones: // checking account withdraw: void c_withdraw(account A, int amt) { A->balance -= amt + A->extra.fee; } // savings account deposit void s_deposit(account A, int amt) { A->balance += amt + A->extra.bonus; } // but how do I make sure that they're called automatically? I have to // implement by myself an automatic "dispatch" mechanism: void withdraw(account A, int amt) { if (A->tag==CHECKING) c_withdraw(A,amt); else withdraw0(A,amt); // call "superclass" method (inherit) } void deposit(account A, int amt) { if (A->tag==SAVINGS) s_deposit(A,amt); else deposit0(A,amt); } /* now I want to distinguish between two kinds of account: checking and savings. checking accounts charge fee during withdraw, savings account adds bonus during deposit. However, the deposit procedure for checking accounts, withdraw for savings accounts, and the inquiry method for both should remain the same. I don't want to redefine two sets of code completely from scratch. I want to "inherit" code that's still usable. Possible approaches: 1. define two different kinds of structs, and use overloading (add overloading to pure C). problem with this approach: how do I inherit existing code? (this is the static type approach) 2. tag each account struct to indicate the type of the account (dynamic type information)*** */ ///////// int main(int argc, char** argv) { account myaccount = newchecking(100,2); account youraccount = newsavings(200,1); withdraw(myaccount,50); // not myaccount->withdraw(50), so what! deposit(youraccount,100); deposit(myaccount,100); printf("my balance is %d\n",inquiry(myaccount)); printf("your balance is %d\n",inquiry(youraccount)); if (moremoney(youraccount,myaccount)) printf("you have more money than I do\n"); return 0; } /* How is this "inferior" to Java? Only real difference so far: everything is public (big deal!) Garbage collection,type safety are other comparisons to Java, but these issues are orthogonal to oop. */