Classes in C++ A class is a data type similar to a C structure. It includes various local data (called data members) together with constructors, destructors and member functions. All of them are called class members. Constructors are designed to provide initial values to the class data and to allocate memory. Destructors are used to deallocate memory. Member functions are designed to manipulate the class data. An object in C++ is an instance of a class (similar to a variable). There are typically many objects for any given class. Using OOP terminology, when we make a call to an object function we are passing a message to the object. Teresa Leyk Slide 1 C++ Review Part 2
Classes in C++ (cont) In many cases, fundamental types is used as types for data members in classes. There are three keywords public, private and protected to control whether objects can access the members of a given class. The public part of a class contains members which are accessible to any object via the dot operator. The private part of a class contains members which are not directly accessible by objects from another class, and can be accessible only indirectly by using public functions of this class. The protected part of a class contains members which can be accessed by objects of a subclass (derived class). There are also global functions or variables in C++ which are not members of any class. Try to limit their use. Teresa Leyk Slide 2 C++ Review Part 2
A Constructor A constructor is a function which always has the same name as the class, and does not have an explicit return type, nor the keyword void. Multiple constructors may be defined in a class. If no constructor is defined, a default constructor is provided by the compiler and that constructor takes no action. A constructor is called when an instance of a class is created. EXAMPLE. A simple class myvect which dynamically creates 1-dimensional arrays (vectors) is presented on the next slide. The class defines two constructors and one destructor. The first constructor is the default constructor. Here is an example of objects being created (in main) using the constructors of the class myvect. myvect z; // default constructor invoked myvect y(100); // 1-arg constructor invoked Teresa Leyk Slide 3 C++ Review Part 2
class myvect { private: int size; // the number of elements in use int capacity; // max number of elements int *ptr; // pointer to the array public: myvect() { size = 0; capacity = 10; ptr = new int[capacity]; myvect(int cap) { size = 0; capacity = cap; ptr = new int[capacity]; ~myvect() { delete [] ptr;... // other class functions ; Teresa Leyk Slide 4 C++ Review Part 2
A Destructor The opposite operation to creating an object is to destroy / remove an object. This is done by the descructor. There is only one destructor per class which returns no value and has no parameters. The name of the destructor is the same as the name of the class prefixed with a tilde (~). If no destructor is defined, a default destructor is provided by the compiler and that destructor takes no action. The destructor is always called when the operator delete is invoked or when a local object is destroyed (when we are leaving a block or function where the object is defined). You cannot overload a destructor. EXAMPLE. When we create a dynamical object (by the operator new), we also need to delete this object using the operator delete. This is shown in the definition of the destructor ~myvect(). Teresa Leyk Slide 5 C++ Review Part 2
A Copy Constructor and Assignment Operator The compiler provides not only a default constructor and destructor but also a default copy constructor and default assignment operator. The copy constructor is called every time a copy of an object is made (for instance, when you pass an object by value into a function). All copy constructors take one parameter: a reference to an object of the same class. It should be a constant reference because the constructor will not have to alter the object passed in. EXAMPLE. This is a copy constructor. Its goal is to make a copy of the object vect. myvect(const myvect &vect); The default copy constructor copies each member variable from the object passed as its formal argument to the member variables of the new object. It creates so called shallow copy which works correctly only if the member variables are not pointers. Teresa Leyk Slide 6 C++ Review Part 2
If at least one member variable is a pointer then the copy constructor should make a deep copy (a copy to newly allocated memory). But then it is necessary to write a corresponding copy constructor and destructor. Here is the copy constructor for the class myvector. By allocating new memory to ptr we create a deep copy of the existing object vect. myvect::myvect(const myvect & vect) { capacity = vect.capacity; ptr = new int[capacity]; for (int i = 0; i < size; i++) ptr[i] = vect.ptr[i]; size = vect.size; // allocate memory // copy contents You may use one object to initialize another object of the same class. Here the object v2 is initialized by copying values from v1. myvect v2(v1);// copy constructor is called to initialize v2 Teresa Leyk Slide 7 C++ Review Part 2
When you write your own copy constructor, you shoud also write a corresponding assignment operator. The assignment operator is called whenever you assign to an object (by using the assignment operator =). myvect & operator=(const myvect & vect){ if (this == &vect) return *this; // avoid self copy delete [] ptr; capacity = vect.capacity; // delete all contents of this object size = vect.size; ptr = new int[capacity]; // allocate memory for (int i = 0; i < size; i++) ptr[i] = vect.ptr[i]; return *this; // copy contents This is an example when an assignment operator is called. myvect v3;... v3 = v1; // copy all elements from v1 to v3 Teresa Leyk Slide 8 C++ Review Part 2
Functions in C++ The purpose of a function is to perform one task. A function declaration consists of: name, list of formal arguments and return type. A function call: invoking a function in main or another function with actual arguments. Types and order of actual arguments must be consistent with types and order of formal arguments (arguments of primitive types do not need to agree exactly because of implicit type conversions). A function may be declared many times but defined only once. A function may be defined in one file and called from other files where only its declaration is provided by a header file. Teresa Leyk Slide 9 C++ Review Part 2
In C++ arguments are passed by: Passing Parameters to a Function value a copy of the value of an actual argument is made to be passed to the function and this value initializes the corresponding formal argument. A modification of the formal argument inside a function does not alter the value of the actual argument. reference a reference (address) of an actual argument is passed to the corresponding formal argument. Any modification of the formal argument inside a function may alter the value of the actual parameter. This is a convenient way to pass a structure or class object to a function. constant reference a reference of an actual argument is passed to the corresponding formal argument with the restriction that the formal argument cannot alter its value inside a function. Teresa Leyk Slide 10 C++ Review Part 2
Passing Parameters to a Function: Example Now we add some functions to the class myvect. They are functions for adding an integer to the last position of the vector and removing an integer from the last position of the vector, a function for replacing an existing integer at a given position (assuming that this position is valid), and a function for printing elements of a vector. class myvect {... // private part, constructors, destructor int get_size() const { return size; int get_elem(int i) const { if (i >= 0 && i < size) return ptr[i]; else return 0; void add(int newelem); int remove(); int replace_at(int pos, int newelem); ; // end of class Teresa Leyk Slide 11 C++ Review Part 2
Passing Parameters to a Function: Example (cont) These functions are usually defined in a separate.cpp file, and the class definition is in a.h file (which is included in this.cpp file by using #include). void myvect::add(int newelem) { if (size < capacity) { ptr[size] = newelem; size++; int myvect::remove() { if (size >= 1) { size--; return ptr[size]; return 0; // this is not a good solution Teresa Leyk Slide 12 C++ Review Part 2
int myvect::replace_at(int pos, int newelem) { if (pos >= 0 && pos < size) { int oldelem = ptr[pos]; ptr[pos] = newelem; return oldelem; return 0; ostream &operator<<(ostream &out, const myvect &v) { out << "("; for (int i = 0; i < v.get_size(); i++) { if (i > 0) out << ", "; out << v.get_elem(i); out << ")"; return out; Teresa Leyk Slide 13 C++ Review Part 2
And here is an example how we can ad, remove and replace vector elements in the main function. int main() { myvect v1; // default constructor v1.add(3); v1.add(2); v1.add(15); v1.add(6); v1.add(-3); v1.add(2); cout << "initial vector:\n"; cout << v1 << endl; v1.remove(); v1.remove(); cout << "the vector after removing 2 elements\n"; cout << v1 << endl; v1.replace_at(0, -7); v1.replace_at(1, -7); cout << "the vector after replacement\n"; cout << v1 << endl; return 0; Teresa Leyk Slide 14 C++ Review Part 2
Function Overloading A function overloading allows to define a function with the same name but different lists of arguments or different type of arguments. The purpose of function overloading is to define similar functions which act on different types of data. Operator overloading is a powerful mechanism but do not abuse it because it is easy to cause confusion to a reader/user of a program. EXAMPLE. We can define the function print which allows to print values of variables of a primitive type as well as structures or objects. In C++, you can overload operators ==,!=, +, +=, *, or << and a few others. For instance, overloading the operator == is useful for comparing two objects of the same class or structure. EXAMPLE. boolean operator ==(const Student &st1, const Student &st2) { return st1.studentid == st2.studentid; The operator << is often overloaded for input and output objects. Teresa Leyk Slide 15 C++ Review Part 2
Friend Functions Any data which is declared private inside a class is not accessible from outside the class. A class can allow non-member functions to access its own private data by making them friends. Once a non-member function is declared as a friend, it can access the private data of the class. Similarly, when a class is declared as a friend of another class, the friend class can have access to the private data of the class which made this a friend. Precondition and Postcondition Precondition: a condition that is supposed to be true before a function is called and the function does not guarantee to return a correct output without satisfying this condition. Postcondition: specifies the meaning of a return value / return arguments from a function or information about its run-time errors. Teresa Leyk Slide 16 C++ Review Part 2
A Specification of a C++ Function To write a specification for a C++ function you need only think about what the function does, not how it does its work. We can follow a format that is guaranteed to provide some kind of information about any function. This documentation is called the function specification. These are five parts of this specification: 1. Short introduction. This includes the function s name, the complete heading, and a short description of the action that the function performs. 2. Parameter description. It is a list of the function s parameters. 3. Precondition. It is a condition that is supposed to be true when a function is called (and the function is not guaranteed to work correctly unless the precondition is true). Teresa Leyk Slide 17 C++ Review Part 2
4. Postcondition (return condition). It specifies the meaning of a function s return value. Some functions may have additional effects beyond a single return value. To describe such effects, a general postcondition can be provided instead of just a returns condition. 5. The throws list. A function should check if a precondition is satisfied. If the precondition fails, then the function throws an exception (it will be discussed later). Teresa Leyk Slide 18 C++ Review Part 2
A Specification of a C++ Function: Example This is a problem to solve: Find the sum of all integers from 0 to n. Here is the program specification. 1. int intsum(int n) // Find a sum of integers from 0 to n. 2. Parameters: n an integer number 3. Precondition: n >= 0 4. Postcondition: returns the sum of integers from 0 to n 5. If error, it returns -1 which indicates that n is a negative number. Here is an implementation. int intsum(int n) { if (n < 0) return -1; // indicates error return n*(n+1)/2; Teresa Leyk Slide 19 C++ Review Part 2