/* Miscellaneous Features of C++. */ using namespace std; #include #include /*** Call by Reference ***/ /* Recall that if you pass an object by value (that is, pass a copy of the object) to a function, any changes to the object stays local. If you pass a pointer to the function, then change to the object are persistant. However, sometimes it's not appropriate to pass a pointer to a function, such as in the case of vectors. Many C++ functions use call by reference, which is in most ways same as passing pointers, but has a different syntax: */ void f1(vector& V) { V[2] = 3; // change is persistent. } /* You can only pass a variable by reference, and any change made by the function to that variable would be the same as changing the variable in its original scope. */ /************** Reference return values ****************/ /* Even more weird than reference parameters are reference return values. This is again similar to returning a pointer. However, a pointer is still a "value", it just so happens to be a memory address. But a "reference" is something that can also be changed. That is, you can assign a value to a function call! */ int x; // global variable int &f2() { return x; } // the statement f2() = 3; would be valid - it would be the same as x=3; // This feature is usually only used together with operator overloading, // as shown below. /************ Optional Parameters ***************/ /* A function in C/C++ can have optional parameters with default values: */ void f3(int x, int y=1, int z=2) { cout << "y is " << y << " and z is " << z << endl; } /* Optional parameters must appear to the right of non-optional ones. If you don't use the optional parameter, the default value will be used instead. Notice that in order to pass a value to z, you must also pass a value to y as well. */ /************ Operator overloading **************/ /* It's possible to redefine the meaning of the operators such as + and == for user-defined classes. */ class rational { public: int numerator; int denominator; rational() {} // default constructor rational(int n, int d) { if (d==0) throw "denominator can't be zero"; numerator = n; denominator = d; } // rational equality overloaded bool operator ==(rational b) { return numerator*b.denominator == denominator*b.numerator; } }; // class rational // rational addition: -- definition can also be outside of class: rational operator +(rational a, rational b) { int d = a.denominator*b.denominator; int n = a.numerator*b.denominator + b.numerator*a.denominator; return rational(n,d); } /* Warning, there are a lot of idiosyncrasies and restrictions regarding the use of operator overloading. Notice I didn't use pointers to objects, for example. Consult full C++ guides. My advice is don't get carried away with them, as overusing them will end up constraining your code instead making it simpler. */ // Demonstrations: int main() { vector A; A.push_back(5); f1(A); cout << A[0] << endl; f2() = 3; cout << x << endl; f3(1,2,3); f3(1,5); rational a(1,2); rational b(1,4); rational c(3,4); rational d = a+b; cout << (d == c) << endl; return 0; }