CPSC 102-001 Computer Science II
(Advanced C Programming)

Fall 2010
09:05-09:55MW Daniel 415
Assignment 4

Objectives:
To implement and test the drgb_t and irgb_t "pixel" classes

Due date:
10/27/10

What to hand in:
A tar.gz archive of your asg4/ directory, including:
  1. A README file containing
    1. Course id--section no
    2. Name
    3. Assignment description
    4. Brief solution description (e.g., program design, description of algorithm, etc., however appropriate).
    5. Lessons learned, identified interesting features of your program
    6. Any special usage instructions
  2. Makefile
  3. source code (.h headers and .cpp source)
  4. object code (do a make clean before tar)
How to hand in:
See handin notes

Description:
  1. Using the code developed in lab 9, namely the vec_t class, provide the drgb_t and irgb_t (pixel) classes to handle manipulation of double and unsigned char pixel data.
  2. Following the class notes, define the drgb_t class in the pixel.h interface, providing the following class member functions:
      // constructors (overloaded)
      drgb_t(double ix=0.0, double iy=0.0, double iz=0.0);
    
      // copy constructor
      drgb_t(const drgb_t& rhs);
    
      // destructors (default ok)
      ~drgb_t();
    
      // assignment operator
      drgb_t& operator=(const drgb_t& rhs);
    
      // compound assignment operator +=, see:
      // http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
      drgb_t& operator+=(const drgb_t& rhs);
    
      // compound assignment operator *=, see:
      // http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
      drgb_t& operator*=(const drgb_t& rhs);
    
      // compound assignment operator *=, see:
      drgb_t& operator*=(const double& s);
    
      // accessors
      const double& operator[](int i) const;
      double& operator[](int i);
    
      // operators
    
      // add this instance's value to rhs, return new instance with result, from:
      // http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
      const drgb_t operator+(const drgb_t& rhs) const;
    
      // mult this instance's value to rhs, return new instance with result, from:
      // http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
      const drgb_t operator*(const drgb_t& rhs) const;
    
      // mult this instance's value to rhs, return new instance with result, from:
      // http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
      const drgb_t operator*(const double& s) const;
    
      // friend operators
      friend drgb_t operator*(const double& s, const drgb_t& rhs);
    
      // friend i/o
      friend std::ostream& operator<<(std::ostream& s, const drgb_t& rhs);
      friend std::ostream& operator<<(std::ostream& s, drgb_t *rhs);
    
      friend std::istream& operator>>(std::istream& s, drgb_t& rhs);
      friend std::istream& operator>>(std::istream& s, drgb_t *rhs);
    
      // members
      bool iszero(void) const;
      void clamp(double min, double max);
    
      // private data members
      private:
      double pix[3];
    		

  3. Following the above, define the irgb_t class in the pixel.h interface, providing corresponding class member functions except for clamp() with private data member:
      private:
      unsigned char pix[3];
    		

  4. Your code should be such that the following main() and test_hits() routines work unaltered:
    int main()
    {
            drgb_t  dp1(1.0, 2.0, 3.0);
            drgb_t  dp2(4.0, 5.0, 6.0);
            drgb_t  dp3, dp4(dp1);
    
      // use operator>> intead of fscanf
      std::cout << "Enter 3 values for dp3"  << std::endl;
      std::cin >> dp3;
    
      // use ostream instead of 'prn' function
      std::cout << "dp1 = " << dp1 << std::endl;
      std::cout << "dp2 = " << dp2 << std::endl;
      std::cout << "dp3 = " << dp3 << std::endl;
      std::cout << "dp4 = " << dp4 << std::endl;
    
      // test operator[]
      dp2[1] = 3.0;
      dp2[0] = dp2[2];
      std::cout << "dp2 = " << dp2 << std::endl;
    
      // test operator*
      std::cout << "dp4 * 5 = " << dp4 * 5 << std::endl;
    
      // test global binary operator*
      std::cout << "3 * dp4 = " << 3 * dp4 << std::endl;
    
            irgb_t  ip1('1', '2', '3');
            irgb_t  ip2('4', '5', '6');
            irgb_t  ip3, ip4(ip1);
    
      // use operator>> intead of fscanf
      std::cout << "Enter 3 values for ip3"  << std::endl;
      std::cin >> ip3;
    
      // use ostream instead of 'prn' function
      std::cout << "ip1 = " << ip1 << std::endl;
      std::cout << "ip2 = " << ip2 << std::endl;
      std::cout << "ip3 = " << ip3 << std::endl;
      std::cout << "ip4 = " << ip4 << std::endl;
    
      // test operator[]
      ip2[1] = '3';
      ip2[0] = ip2[2];
      std::cout << "ip2 = " << ip2 << std::endl;
    
      // test double to unsigned char casting
      for(int i=0;i<3;i++) ip4[i] = dp4[i];
      std::cout << "ip4 = " << std::endl;
      for(int i=0;i<3;i++) std::cout.put(ip4[i]);
      std::cout << std::endl;
    }
    		
  5. Sample input (entered by user):
    7 8 9
    7 8 9
    		
  6. Sample output (the output following ip4 = is not visible; bold text indicates user input):
    Enter 3 values for dp3
    7 8 9
    dp1 = 1 2 3
    dp2 = 4 5 6
    dp3 = 7 8 9
    dp4 = 1 2 3
    dp2 = 6 3 6
    dp4 * 5 = 5 10 15
    3 * dp4 = 3 6 9
    Enter 3 values for ip3
    7 8 9
    ip1 = 1 2 3
    ip2 = 4 5 6
    ip3 = 7 8 9
    ip4 = 1 2 3
    ip2 = 6 3 6
    ip4 =