// C++ Cheat Sheet for CMSC 331 // revised 10/2/2013 // comments look like this /* or like this */ // use the command g++ cppcs.cpp to compile this file on gl #include // the built-in stream I/O package using namespace std; // a relatively new feature in C++ #include // This is C's assert macro, which works fine in C++ // class rational // inspired largely by Budd's well-known data structures textbook class rational { public: // these member functions can be called from anywhere /* constructors have the same name as the class itself */ // these are function DECLARATIONS, not DEFINITIONS. Those come later. rational (); rational (int); rational (int,int); // const keyword keeps the object from being modified rational (const rational &); // destructors, if any, are named ~class e.g. // ~rational(); /* accessor functions */ int numerator () const; int denominator () const; /* assignments */ // could add *=, /=, and so forth // note the over-loading of = and += operators already in C++ void operator = (const rational &); void operator += (const rational &); /* arithmetic */ // friend functions aren't member functions of the class, but // they can still access private data friend rational operator + (const rational &, const rational &); friend rational operator - (const rational &, const rational &); friend rational operator - (const rational &); // unary -, i,e, negation /* comparison */ friend bool operator < (const rational &, const rational &); friend bool operator > (const rational &, const rational &); friend bool operator == (const rational &left, const rational &right); /* output */ friend ostream & operator << (ostream &, const rational &); private: // private data is only visible from member functions // of this class or derived classes, or friend functions /* data areas */ // in fractions, int top; // top can be pos or neg int bottom; // but let's make sure bottom is positive }; // Constructors // to have several forms of a given constructor for different // number and type of arguments is very common rational::rational() // make zero the default value { top = 0; // could also say this.top = 0; where this points to the current object bottom = 1; } rational::rational(int numerator) // integer x becomes rational x/1 { top = numerator; bottom = 1; } rational::rational(int numerator, int denominator) { assert( denominator != 0 ); // because that's bad top = numerator; // n.b. several functions with same name bottom = denominator; } rational::rational(const rational & value) // use one rational to { // initialize another // const qualifier prevents this member function from changing // the value - even though value's private data is visible! top = value.numerator(); // using accessor is not that different from bottom = value.bottom; // using private data } // Accessors int rational::numerator() const { return top; } int rational::denominator() const { return bottom; } // Assignments void rational::operator = (const rational &right) { top = right.numerator(); bottom = right.denominator(); } void rational::operator += (const rational &right) // try adding 1/2 to 3/2 and then // try adding 1/2 to 1/4 to see how this works { top = top * right.denominator() + right.numerator() * bottom; bottom = bottom * right.denominator(); } // another version of this function //void rational::operator += (const rational &right) // try adding 1/2 to 3/2 to see how this works //{ // this = this+right; //} // Arithmetic rational operator + (const rational &left, const rational &right) { rational result( left.numerator() * right.denominator() + right.numerator() * left.denominator(), left.denominator() * right.denominator()); return result; } rational operator - (const rational &left, const rational &right) { rational result( left.numerator() * right.denominator() - right.numerator() * left.denominator(), left.denominator() * right.denominator()); return result; } rational operator - (const rational &r) // unary minus is negation { // create a rational == 0 using the appropriate constructor return (0 - r); } // multiplication and division could be defined in a similar fashion // Comparison bool operator < (const rational &left, const rational &right) { return (left.numerator() * right.denominator()) < (right.numerator() * left.denominator()); } bool operator > (const rational &left, const rational &right) { return (left.numerator() * right.denominator()) > (right.numerator() * left.denominator()); } bool operator == (const rational &left, const rational &right) { return (left.numerator() * right.denominator() == left.denominator() * right.numerator()); } // <= and >= and != could be defined in a similar fashion // I/O (well, just O for the time being) ostream & operator << (ostream & ostr, const rational &r) { ostr << r.numerator() << "/" << r.denominator(); } // Other functions - not members or friends // although it would be easy enough to change that... rational invert(const rational &r) { assert( r.numerator() != 0 ); return rational(r.denominator(), r.numerator()); } rational abs(const rational &r) { if (r < 0) { return -r; } else { assert( (r == 0) || (r > 0) ); // demonstrate assert return r; } } int main() { cout << "Hello, world!" <