home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IDIOMS.ZIP / 5-8.C < prev    next >
C/C++ Source or Header  |  1991-12-04  |  4KB  |  173 lines

  1. /* Copyright (c) 1992 by AT&T Bell Laboratories. */
  2. /* Advanced C++ Programming Styles and Idioms */
  3. /* James O. Coplien */
  4. /* All rights reserved. */
  5.  
  6. #include <iostream.h>
  7. #include <stdio.h>
  8.  
  9. struct BaseConstructor { BaseConstructor(int=0) { } };
  10.  
  11. class Number {
  12. public:
  13.     Number(BaseConstructor);
  14.     Number();
  15.     Number(double d);
  16.     Number(double rpart, double ipart);
  17.     Number operator=(Number & n) {
  18.     printf("Number::operator=(Number&)\n");
  19.         n.rep->referenceCount++;
  20.         if (--rep->referenceCount == 0) delete rep;
  21.         rep = n.rep;
  22.         return *this;
  23.     }
  24.     void redefine(Number *n) {
  25.     printf("Number::redefine(Number*)\n");
  26.         if (--rep->referenceCount == 0) delete rep;
  27.         rep = n;
  28.     }
  29.     Number(Number & n) {
  30.     printf("Number::Number(Number&)\n");
  31.         n.rep->referenceCount++;
  32.         rep = n.rep;
  33.     }
  34.     virtual ostream& operator<<(ostream &s) {
  35.     printf("Number::operator<<(ostream&)\n");
  36.         return rep->operator<<(s);
  37.     }
  38.     virtual Number operator+(Number &n) {
  39.     printf("Number::operator+(Number&)\n");
  40.         return rep->operator+(n);
  41.     }
  42.     virtual Number complexAdd(Number &n) {
  43.     printf("Number::complexAdd(Number&)\n");
  44.         return rep->complexAdd(n);
  45.     }
  46.     virtual Number doubleAdd(Number &n) {
  47.     printf("Number::doubleAdd(Number&)\n");
  48.         return rep->doubleAdd(n);
  49.     }
  50. private:
  51.     union {
  52.         Number *rep;
  53.         short referenceCount;
  54.     };
  55. };
  56.  
  57. class Complex: public Number {
  58. friend class RealNumber;
  59. public:
  60.     Complex(double d, double e): Number(BaseConstructor()) {
  61.     printf("Complex::Complex(double, double)\n");
  62.         rpart = d; ipart = e;
  63.     }
  64.     Number operator+(Number &num) {
  65.     printf("Complex::operator+(Number&)\n");
  66.         Number n = num.complexAdd(*this);
  67.         return n;
  68.     }
  69.     Number complexAdd(Number &n);
  70.     Number doubleAdd(Number &n);
  71.     ostream& operator<<(ostream& o) {
  72.         o << "Complex(" << rpart << "," << ipart << ")";
  73.         return o;
  74.     }
  75. private:
  76.     double rpart, ipart;
  77. };
  78.  
  79. class RealNumber: public Number {
  80. friend Complex;
  81. public:
  82.     RealNumber(double d): Number(BaseConstructor()) {
  83.     printf("RealNumber::RealNumber(double)\n");
  84.         r = d;
  85.     }
  86.     Number operator+(Number &num) {
  87.     printf("RealNumber::operator+(Number&)\n");
  88.         Number newnum = num.doubleAdd(*this);
  89.         return newnum;
  90.     }
  91.     Number complexAdd(Number &n);
  92.     Number doubleAdd(Number &n) {
  93.     printf("RealNumber::doubleAdd(Number&)\n");
  94.         Number retval;
  95.         RealNumber *c1 = new RealNumber(*this);
  96.         RealNumber *c2 = (RealNumber*)&n;
  97.         c1->r += c2->r;
  98.         retval.redefine(c1);
  99.         return retval;
  100.     }
  101.     ostream& operator<<(ostream& o) {
  102.     printf("RealNumber::operator<<(ostream&)\n");
  103.         o << "Float(" << r << ")";
  104.         return o;
  105.     }
  106. private:
  107.     double r;
  108. };
  109.  
  110. ostream& operator<<(ostream&o, Number n) {
  111.     Number *np = &n;
  112.     return np->operator<<(o);
  113. }
  114.  
  115. Number::Number(BaseConstructor) {
  116.     printf("Number::Number(BaseConstructor)\n");
  117.     referenceCount = 1;
  118. }
  119.  
  120. Number::Number() {
  121.     printf("Number::Number()\n");
  122.     rep = new RealNumber(0.0);
  123. }
  124.  
  125. Number::Number(double d) {
  126.     printf("Number::Number(double)\n");
  127.     rep = new RealNumber(d);
  128. }
  129.  
  130. Number::Number(double d, double e) {
  131.     printf("Number::Number(double,double)\n");
  132.     rep = new Complex(d, e);
  133. }
  134.  
  135. Number Complex::complexAdd(Number &n) {
  136.     printf("Number::complexAdd(Number&)\n");
  137.     Number retval;
  138.     Complex *c1 = new Complex(*this);
  139.     Complex *c2 = (Complex*)&n;
  140.     c1->rpart += c2->rpart;
  141.     c1->ipart += c2->ipart;
  142.     retval.redefine(c1);
  143.     return retval;
  144. }
  145.  
  146. Number Complex::doubleAdd(Number &n) {
  147.     printf("Complex::doubleAdd(Number&)\n");
  148.     Number retval;
  149.     Complex *c1 = new Complex(*this);
  150.     RealNumber *c2 = (RealNumber*)&n;
  151.     c1->rpart += c2->r;
  152.     retval.redefine(c1);
  153.     return retval;
  154. }
  155.  
  156. Number RealNumber::complexAdd(Number &n) {
  157.     printf("RealNumber::complexAdd(Number&)\n");
  158.     Number retval;
  159.     Complex *c1 = new Complex(r, 0);
  160.     Complex *c2 = (Complex*)&n;
  161.     c1->rpart += c2->rpart;
  162.     c1->ipart += c2->ipart;
  163.     retval.redefine(c1);
  164.     return retval;
  165. }
  166.  
  167. int main() {
  168.     Number a = Number(1.0, 1.0);
  169.     Number b = 2.0;
  170.     Number c = a + b;
  171.     cout << "a = " << a << ", b = " << b << ", c = " << c << "\n";
  172. }
  173.