Financial Computing with C++, Lecture 4 - p1/19 Financial computing with C++ LG Gyurkó University of Oxford Michaelmas Term 2015
Financial Computing with C++, Lecture 4 - p2/19 Outline General properties of classes Members of classes Constructors and destructors Special members - overloaded operators
Financial Computing with C++, Lecture 4 - p3/19 Outline of the course Programming is learned by writing programs. Brian Kernighan
Financial Computing with C++, Lecture 4 - p4/19 Outline of this lecture - creating new types Man: Look, Ivan! My own hybrid of a potato and tomato! Ivan: And this should be a potato below-ground and a tomato above-ground? Man: Precisely! Ivan: And where are the tomatoes? I can t see anything! Man: It s too early, it s only March.... Man: Last year, it did not succeed. The leaves were that of a potato and the roots that of a tomato. Ivan: Then your hybrid sucks. Life and Extraordinary Adventures of Private Ivan Chonkin
Financial Computing with C++, Lecture 4 - p5/19 Types We have seen types provided by the core language. In C++ it s possible to implement custom types. What is a type? Collection of states described by some data members Behaviour implemented by member functions (methods)
Financial Computing with C++, Lecture 4 - p6/19 Classes - ComplexNumber, the interface Example: ComplexNumber is a class with a few members. (The example is taken from Exceptional C++ by Herb Sutter with minor modifications.) 1 #include <iostream> 2 3 class ComplexNumber 4 { 5 public: 6 ComplexNumber(); 7 explicit ComplexNumber(double, double=0.0); 8 9 ComplexNumber & operator+=(const ComplexNumber &); 10 ComplexNumber & operator-=(const ComplexNumber &); 11 ComplexNumber & operator*=(const ComplexNumber &); 12 ComplexNumber & operator/=(const ComplexNumber &); 13 14 ComplexNumber & operator+=(const double &); 15 ComplexNumber & operator-=(const double &); 16 ComplexNumber & operator*=(const double &); 17 ComplexNumber & operator/=(const double &); 18 19 std::ostream & print(std::ostream &) const; 20 21 private: 22 double dre_; 23 double dim_; 24 };
Financial Computing with C++, Lecture 4 - p7/19 General properties of classes we distinguish between class (the type) and instance of a class (a particular value) classes can have public, private and protected members or properties (members of each category can exists simultaneously in one class) public members are accessible without restrictions (by any function or type) private members of an instance C of class type_of_c are only accessible by instances of the same class type_of_c and objects declared as friend of type_of_c (examples... maybe later). protected members of an instance C of class type_of_c are accessible by friend s and instances of classes derived from type_of_c. (... later) members of a class can be data and function. unless otherwise specified, class members are private by default struct is similar to class, however struct members are public by default the keywords class and struct are required when declaring a class or struct respectively. members can be accessed (given the permission) using the operator. : C.data or C.fun(); or members can be accessed through pointers using the operator ->: C_ptr->data, C_ptr->fun()
Financial Computing with C++, Lecture 4 - p8/19 Members - in general Member functions member functions of a class are part of its namespace members functions take the instance they are called from as an argument, although the instance is not explicitly listed in the argument list the instance is a const argument, if the member is declared const, note the syntax: fun(...) const; member functions can return reference to the instance the function was called from, this can be achieved by dereferencing the pointer this to self. Don t give access to the class non-public members if it s not necessary. In other words: Prefer non-member non-friend functions to member functions. (Scott Meyers, Effective C++)
Financial Computing with C++, Lecture 4 - p9/19 Members - in general Data members data members can be plain values, references, pointers and const versions of these const and reference members must be declared at the construction of the instance it s recommended to make data members non-public, although in some cases public data members are useful (e.g. first and second are public members of pair<t1,t2>)
Financial Computing with C++, Lecture 4 - p10/19 Classes - ComplexNumber, members 1 class ComplexNumber 2 { 3 4 private: 5 double dre_; 6 double dim_; 7 }; ComplexNumber has two private members, both are data members
Financial Computing with C++, Lecture 4 - p11/19 Classes - ComplexNumber, members 1 class ComplexNumber 2 { 3 public: 4 ComplexNumber(); 5 explicit ComplexNumber(double, double=0.0); 6 7 ComplexNumber & operator+=(const ComplexNumber &); 8 9 std::ostream & print(std::ostream &) const; ComplexNumber a few member functions, each of them is public the member print() is a const function (does not modify the data members), the other functions or non-const members.
Financial Computing with C++, Lecture 4 - p12/19 Member functions - constructors & destructors constructors initialize instances of classes, destructors take care of destroying the instance constructors and destructors return nothing constructors initialize data members, if initialization is not done explicitly, the compiler will call the default constructor of the data members (even if there are assignments in the function body) initializing data from constructors has a special syntax (see examples) default constructors take no arguments If no constructor is declared, the compiler will create a default constructor, which initializes the data members calling their default constructors copy constructors take an instance of the same type (usually by const reference) and create a new instance from that If no copy constructor is declared, the compiler will create one, which initializes the data members calling their copy constructors. If no destructor is declared, the compiler will create one. Note that the compiler generated default constructor, copy constructor and destructor might not work properly in certain cases. (See Effective C++ by Scott Meyers for further details.)
Financial Computing with C++, Lecture 4 - p13/19 Classes - ComplexNumber, constructors and destructors 1 class ComplexNumber 2 { 3 public: 4 ComplexNumber(); 5 explicit ComplexNumber(double, double=0.0); A default constructor is declared (an defined somewhere), the compiler generated one might not initialize the data members to 0 A second constructor is declared, takes two double s, specifies a default value to the second argument. The argument with a default value might be omitted from the call, and its default value will be passed automatically. Note the explicit keyword. It protects against implicit type conversion (see Effective C++ by Scott Meyers, or Exceptional C++ by Herb Sutter for details). No copy constructor is declared, the one generated by the compiler will copy the data members, which is fine here. No destructor is declared, the compiler will generate one.
Financial Computing with C++, Lecture 4 - p14/19 Classes - ComplexNumber, constructors and destructors The class is implemented in Practical02/ComplexNumber.cpp : 1 #include "ComplexNumber.hpp" 2 3 4 ComplexNumber::ComplexNumber() : dre_(0.0), dim_(0.0) {} 5 6 ComplexNumber::ComplexNumber(double drearg, double dimarg) 7 : dre_(drearg), dim_(dimarg) {} The usual practice is to put the class declaration into a header file and the implementation into a cpp file. Note that the header file must be #include ed in the cpp file to give access to the declarations. A default constructor initializes both data members to 0. Nothing is done beyond initialization, that s why the function body is empty. The second constructor initializes the data members to the values provided by the arguments. If no second argument is specified by the call, the default value 0 will be taken. The function body is empty. Note the use of the namespace ComplexNumber:: when accessing the function members of ComplexNumber for implementation.
Financial Computing with C++, Lecture 4 - p15/19 Special members - overloaded operators one can overload most of the C++ operators (see lecture 2 for a list of available operators) the declaration of operator members have a special syntax: 1 class ComplexNumber 2 { 3 public: 4 ComplexNumber & operator+=(const ComplexNumber &); i.e. operator members have a special name, built of the keyword operator and the sign of the operator. the typical two argument operators (e.g. +=, -=, <, <= etc.) can be called two in equivalent ways, e.g.: C1<C2 is equivalent to C1.operator<(C2) a special operator is the () operator () can be called in the form: C1.operator()(arguments) or C1(arguments) the latter form looks like a calling a simple function named C1, that s why classes with operator () implemented are referred to as function objects. the operator = with argument (const reference to) the user-defined class is the copy assignment. If no copy assignment is declared, the compiler will generate one.
Financial Computing with C++, Lecture 4 - p16/19 Special members - operator () example Example: Call option payoff 1 class CallOption 2 { 3 public: 4 CallOption(double darg=1.0) : dk_(darg) {} 5 6 double operator()(double darg) { 7 return (darg<dk_)? 0.0 : darg-dk_; 8 } 9 10 private: 11 double dk_; 12 }; The class CallOption has an overloaded operator () member, taking a double and returning a double The operator () is called in the following example. 1 // construction and usage 2 CallOption Call1(1.0); //construction 3 cout << "Payoff at S=1.5, K=1 is " << Call1(1.5) << endl; 4 // alternatively, using a temp object: 5 cout << "Payoff at S=1.5, K=1 is " << CallOption(1.0)(1.5) << endl;
Financial Computing with C++, Lecture 4 - p17/19 ComplexNumber - operator implementation 1 ComplexNumber & ComplexNumber::operator+=(const ComplexNumber & cnarg) 2 { 3 dre_+=cnarg.dre_; 4 dim_+=cnarg.dim_; 5 return *this; 6 } operator += was made a member, because it accesses private members it returns a reference to the instance it was called from using the dereferenced this pointer this makes expressions like (a+=b)*=c valid once operator += is declared as member, the operator + can be implemented using operator +=, i.e. without accessing non-public members of ComplexNumber, therefore it is declared as global function and implemented as follows: 1 ComplexNumber operator+(const ComplexNumber & Arg1, 2 const ComplexNumber & Arg2) 3 { 4 ComplexNumber Res(Arg1); 5 return Res+=Arg2; 6 }
Financial Computing with C++, Lecture 4 - p18/19 ComplexNumber - operator implementation the operator << must be overloaded to display instances of user defined classes for displaying, usually the access of non-public members is required one way is to declare the global operator << a friend of the new class (see later) or implement a convenience public member: 1 std::ostream & ComplexNumber::print(std::ostream & os) const 2 { 3 return os << "(" << dre_ << ", " << dim_ << "i)"; 4 } now, operator << can be implemented using the member print note that this global function takes an ostream by reference and returns a reference to the same ostream the second argument of type ComplexNumber is the one to be displayed 1 std::ostream & operator<<(std::ostream & os, const ComplexNumber & cnarg) 2 { 3 return cnarg.print(os); 4 }
Financial Computing with C++, Lecture 4 - p19/19 Summary custom types data member public constructor operators class member function private destructor overloading operator() ostream operator << this