230 likes | 355 Views
CSE 20232 Lecture 21 – Classes. De Morgan’s Law C++ Class related concepts Friend functions Overloading operators Circles : an example using Point class Line class Circle class Curses I/O. De Morgan’s Law. When discussing logical expressions we should have discussed De Morgan’s Law
E N D
CSE 20232Lecture 21 – Classes • De Morgan’s Law • C++ Class related concepts • Friend functions • Overloading operators • Circles: an example using • Point class • Line class • Circle class • Curses I/O
De Morgan’s Law • When discussing logical expressions we should have discussed De Morgan’s Law • Given two boolean expressions (p, q) … • De Morgan’s Law states … • not (p and q) == (not p) or (not q) • not (p or q) == (not p) and (not q) • In C++ this gives us … • !(p && q) == (!p) || (!q) • !(p || q) == (!p) && (!q)
De Morgan’s Law (example) • Checking whether value is outside two bounds low and hi … • if ( ! ((low <= value) && (value <= hi)) ) • Is the same as … • if ( (!(low <= value)) || (!(value <= hi)) ) • Is the same as … • if ( (low > value) || (value > hi) )
Reading • Classes • Textbook sections • 3.1 – 3.10 • 9.1 – 9.10
Friend functions • A friend function is a … • Non-member function • Has access to the private portions of the class • Is declared within the class declaration • Is granted friend status by the class • Is often used to create class specific operators • For input and output • For math or other “combining” operations based on class objects
Operators • An operator in C++ is any symbol with an associated operation • Math operators: + - * % / • I/O operators: >> << • Boolean operators: && || ! • Comparison operators: < <= > >= == != • You cannot redefine an operator with respect to an existing class • BUT, you can define its meaning with respect to any new class you create
Overloading • Anytime you create a function or an operator that has the same name as an existing one, you have overloaded that function or operator • The compiler resolves the question “Which version do I use?” by examining the function and operator signatures • Examples: • swap(int&,int&); vs. swap(float&,float&); • Concatenating strings: (firstname + lastName) vs. • Adding ints: (first + second)
The point class // a point in the 2-D Cartesian plane class point { // new and improved – includes helper & utility functions friend point operator* (double s, point p); // performs s*p public: point(double x = 0.0, double y = 0.0); double getX(); double getY(); void get(double &x, double &y); void setX(double x); void setY(double y); void set(double x, double y); point operator+ (point p); // adds p to this point void show(point origin, int maxX, int maxY); // shows point private: double xPosit, yPosit; // hidden data members };
Point class functions // constructor – default (0,0) point::point(double x, double y) : xPosit(x), yPosit(y) { } // accessors – get copies of current x and y coordinates double point::getX() { return xPosit; } double point::getY() { return yPosit; } void point::get(double &x, double &y) { x = xPosit; y = yPosit; }
Point class functions // mutators – change values of x and/or y coordinates void point::setX(double x) { xPosit = x; } void point::setY(double y) { yPosit = y; } void point::set(double x, double y) { xPosit = x; yPosit = y; }
Point related math operators // member function (overloaded + operator) to sum two points point point::operator+(point p) { point result((xPosit + p.xPosit), (yPosit + p.yPosit)); // could also have been ... // point result((this->xPosit + p.xPosit), // (this->yPosit + p.yPosit)); return result; } // friend function to perform premultiplication of point by // a scalar ... (s * p) point operator*(double s, point p) { point result(s*p.xPosit, s*p.yPosit); return result; }
Point show() function // show point on console using curses I/O void point::show(point origin, int maxX, int maxY) { int x = (int)round(origin.xPosit + 2*xPosit); // 2 for aspect ratio y = (int)round(origin.yPosit - yPosit); // Y axis is inverted if ((x < 0) || (x > maxX) || (y < 0) || (y > maxY)) return; move(y,x); printw(“o”); }
Circle class // circle in the 2-D Cartesian plane class circle { friend circle operator*(double s, circle c); // scale (s * radius) public: circle(point c = point(0.0,0.0), double r = 1.0); double getSize(); point getCenter(); void setSize(double r); void setCenter(point c); circle operator+(point p); // translate (center + p) circle operator*(double s); // scale (radius * s) void show(); private: point center; double radius; };
Circle class functions // constructor – default center(0,0) and radius 1 circle:: circle(point p, double r) : center(p), radius(r) { } // accessors – get copies of current center and radius double circle ::getSize() { return radius; } point circle ::getCenter() { return center; }
Circle class functions // mutators – change values of center and radius void circle::setSize(double r) { if (radius < 0.0) return; // do not change radius, if new value is negative radius = r; } void circle::setCenter(point c) { center = c; }
Circle related math operators // member function (overloaded + operator) to translate circle circle circle::operator+(point p) { return circle((center + p), radius); } // friend function to perform scaling of circle(s * p) circle operator*(double s, circle c) { return circle(c.center, (s * c.radius)); } // member function to perform scaling of circle (c * s) circle circle::operator*(double s) { return circle(center, s*radius); }
Circle show() function // chow point on console using curses I/O void circle::show(point origin, int maxX, int maxY) { const double deg2rad = 3.14159/180.0; int cx = center.getX(); int cy = center.getY(); for (int angle=0; angle<90; angle += 10) { int x = (int)round(radius*cos(angle*deg2rad)); int y = (int)round(radius*sin(angle*deg2rad)); point p; p.set((cx + x), (cy - y)); p.show(origin, maxX, maxY); p.set((cx - x), (cy - y)); p.show(origin, maxX, maxY); p.set((cx + x), (cy + y)); p.show(origin, maxX, maxY); p.set((cx - x), (cy + y)); p.show(origin, maxX, maxY); } }
cdemo - Using points & circles // cdemo.cpp - JHS 2006 // CSE 20232 - C/C++ Programming - Notre Dame // This illustrates use of user defined classes (point & circle) // and curses I/O. A single circle is movable and resizable // in response to user input. #include <iostream> #include <curses.h> #include "circle.h" // note: circle.h includespoint.h using namespace std; int main() { circle disk; int key; int width, height; point origin; // this will be in center of window MEVENT event; // for details of mouse clicks
cdemo (continued – 2) // intitialize curses I/O initscr(); getmaxyx(stdscr, height, width); origin.set(width/2, height/2); // set origin to window center raw(); cbreak(); noecho(); keypad(stdscr, TRUE); // allow use of arrows & mouse mousemask(ALL_MOUSE_EVENTS, NULL);// detect all the mouse events do { // clear screen, show disk, position & size and wait for input clear(); // draw disk relative to origin and within bounds of window disk.show(origin, width-1, height-1); mvprintw(0,width-27,"<< The Disk (c) 2006 JHS >>"); mvprintw(0,0,"Disk: center(%3d,%3d) radius(%7.3f)", (int)disk.getCenter().getX(), (int)disk.getCenter().getY(), disk.getSize());
cdemo (continued – 3) mvprintw(height-1,0,"Use arrow keys to move or +/- to %s”, “modify circle (q to quit) "); refresh(); key = getch(); // get user input switch (key) { case KEY_UP: disk = disk + point(0.0,1.0); // move disk up one unit break; case KEY_DOWN: disk = disk + point(0.0,-1.0); // move disk down one unit break; case KEY_LEFT: disk = disk + point(-1.0,0.0); // move disk left one unit break; case KEY_RIGHT: disk = disk + point(1.0,0.0); // move disk right one unit break;
cdemo (continued – 4) case '+': disk = 1.25 * disk; // scale disk up to 125% break; case '-': disk = disk * 0.8; // scale disk down to 80% break; case KEY_MOUSE: if (getmouse(&event) == OK) if (event.bstate & BUTTON1_PRESSED) disk.setCenter( // disk to cursor location point((event.x-origin.getX())/2, origin.getY()-event.y)); // Y is inverted else if (event.bstate & BUTTON2_PRESSED) disk.setCenter(point(0.0,0.0)); // disk to origin else if (event.bstate & BUTTON3_PRESSED) disk.setSize(1.0); // disk size rest to 1.0 break; }
cdemo (continued – 5) // main do-while loop } while ((key != 'q') && (key != 'Q')); // quit on 'q' or 'Q' // clean up, and end curses I/O clear(); refresh(); endwin(); return 0; }