C++ Programming. Classes, Constructors, Operator overloading (Continued) M1 Math Michail Lampis

Similar documents
Implementing vector<>

C++ Programming. Pointers and Memory Management. M1 Math Michail Lampis

Operator overloading

Week 8: Operator overloading

Class Vector: Interface CSE 143. Dynamic Memory In Classes [Chapter 4, p ] Vector Implementation. Many Ways to Implement. Draw the picture!

Use the dot operator to access a member of a specific object.

ADTs in C++ In C++, member functions can be defined as part of a struct

GEA 2017, Week 4. February 21, 2017

QUIZ on Ch.5. Why is it sometimes not a good idea to place the private part of the interface in a header file?

CSE 374 Programming Concepts & Tools. Hal Perkins Fall 2015 Lecture 19 Introduction to C++

CSE 303: Concepts and Tools for Software Development

III. Classes (Chap. 3)

Review Questions for Final Exam

CSCI 123 Introduction to Programming Concepts in C++

Unit 14. Passing Arrays & C++ Strings

And Even More and More C++ Fundamentals of Computer Science

Suppose we find the following function in a file: int Abc::xyz(int z) { return 2 * z + 1; }

Problem Set 1. You might want to read Chapter 12 of the course reader before attempting this problem.

EE 355 Unit 10. C++ STL - Vectors and Deques. Mark Redekopp

IS0020 Program Design and Software Tools Midterm, Fall, 2004

University of Illinois at Urbana-Champaign Department of Computer Science. First Examination

Introducing C++ to Java Programmers

Introduction Of Classes ( OOPS )

COMP 2355 Introduction to Systems Programming

QUIZ Friends class Y;

CS93SI Handout 04 Spring 2006 Apr Review Answers

Praktikum: Entwicklung interaktiver eingebetteter Systeme

Introduction to Linked Lists. Introduction to Recursion Search Algorithms CS 311 Data Structures and Algorithms

Part I: Short Answer (12 questions, 65 points total)

Review: C++ Basic Concepts. Dr. Yingwu Zhu

Topics. bool and string types input/output library functions comments memory allocation templates classes

Engineering Tools III: OOP in C++

COEN244: Class & function templates

Classes in C++98 and C++11

EINDHOVEN UNIVERSITY OF TECHNOLOGY Department of Mathematics and Computer Science

Outline. User-dened types Categories. Constructors. Constructors. 4. Classes. Concrete classes. Default constructor. Default constructor

CMSC 202 Section 010x Spring Justin Martineau, Tuesday 11:30am

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

Classes, Constructors, etc., in C++

Short Notes of CS201

COSC 2P95 Lab 5 Object Orientation

CSC1322 Object-Oriented Programming Concepts

Allocation & Efficiency Generic Containers Notes on Assignment 5

CS201 - Introduction to Programming Glossary By

Object-Oriented Programming for Scientific Computing

Chapter 6: User-Defined Functions. Objectives (cont d.) Objectives. Introduction. Predefined Functions 12/2/2016

Object oriented programming

Chapter 9: Pointers Co C pyr py igh i t gh Pear ea so s n n E ducat ca io i n, n Inc. n c.

Exceptions and Design

Review Questions for Final Exam KEY

C++ PROGRAMMING LANGUAGE: CLASSES. CAAM 519, CHAPTER 13

Consider the program...

C++ assign array values. C++ assign array values.zip

Practice test for midterm 2

Lecture 8. Xiaoguang Wang. February 13th, 2014 STAT 598W. (STAT 598W) Lecture 8 1 / 47

Chapter 17 vector and Free Store

3.Constructors and Destructors. Develop cpp program to implement constructor and destructor.

EECS402 Lecture 02. Functions. Function Prototype

Exam 3 Chapters 7 & 9

Lecture on pointers, references, and arrays and vectors

G52CPP C++ Programming Lecture 13

CS 61B, Spring 1996 Midterm #1 Professor M. Clancy

Lab 2: Pointers. //declare a pointer variable ptr1 pointing to x. //change the value of x to 10 through ptr1

First Examination. CS 225 Data Structures and Software Principles Spring p-9p, Tuesday, February 19

CS102 C++ Exception Handling & Namespaces

During the course of writing the Matrix class we will cover some interesting C++ topics. Specically: constructors and destructors, operator

Operating Systems CMPSCI 377, Lec 2 Intro to C/C++ Prashant Shenoy University of Massachusetts Amherst

Intermediate Programming, Spring 2017*

COMP6771 Advanced C++ Programming

CMSC 202 Midterm Exam 1 Fall 2015

C++_ MARKS 40 MIN

Fibonacci in Lisp. Computer Programming: Skills & Concepts (CP1) Programming Languages. Varieties of Programing Language

Programming Abstractions

Lecture 7. Log into Linux New documents posted to course webpage

! A data structure representing a list. ! A series of nodes chained together in sequence. ! A separate pointer (the head) points to the first

Interview Questions of C++

CS201- Introduction to Programming Current Quizzes

C:\Temp\Templates. Download This PDF From The Web Site

Programming C++ Lecture 2. Howest, Fall 2014 Instructor: Dr. Jennifer B. Sartor

CS302 Midterm Exam Answers & Grading James S. Plank September 30, 2010

Chapter 17 vector and Free Store. Bjarne Stroustrup

! Determine if a number is odd or even. ! Determine if a number/character is in a range. - 1 to 10 (inclusive) - between a and z (inclusive)

Programming Abstractions

CS 240 Data Structure Spring 2018 Exam I 03/01/2018

Class Destructors constant member functions

EL2310 Scientific Programming

! Determine if a number is odd or even. ! Determine if a number/character is in a range. - 1 to 10 (inclusive) - between a and z (inclusive)

Patterns: Working with Arrays

C++ 8. Constructors and Destructors

Assignment of Objects

Programming C++ Lecture 3. Howest, Fall 2012 Instructor: Dr. Jennifer B. Sartor

University of Illinois at Urbana-Champaign Department of Computer Science. First Examination

Part VII. Object-Oriented Programming. Philip Blakely (LSC) C++ Introduction 194 / 370

! Determine if a number is odd or even. ! Determine if a number/character is in a range. ! Assign a category based on ranges (wind speed)

Linked List using a Sentinel

Do not write in this area TOTAL. Maximum possible points: 75

CSE 333 Midterm Exam Cinco de Mayo, 2017 (May 5) Name UW ID#

CPSC 427: Object-Oriented Programming

A function is a named piece of code that performs a specific task. Sometimes functions are called methods, procedures, or subroutines (like in LC-3).

CPSC 427: Object-Oriented Programming

Transcription:

C++ Programming Classes, Constructors, Operator overloading (Continued) M1 Math Michail Lampis michail.lampis@dauphine.fr

Classes These (and the previous) slides demonstrate a number of C++ features related to classes: Data encapsulation Operator overloading Constructors/Destructors and memory management In this set of slides we continue on the same set of topics with another example: a vector class.

A vector class In mathematics, a vector is just an ordered collection of numbers A vector in R^2 is a point on the plane A vector in R^3 is a point in space We can also consider vectors in R^n The closest thing to vectors in C/C++ is arrays

A vector class Let's try to design a vector class that works similar to arrays but with some improved features: Bounds-checking Resizing Assignment (v1 = v2) Mathematical operations...

Prototype #include <iostream> using namespace std; class Vector { int size; double *data; public: Vector(int); //must supply a size ~Vector(); int get_size(); void set_size(int); double read_element(int); void write_element(int,double); friend ostream& operator<<(ostream &, Vector &); };

About the prototype How are we planning to implement Vector? Essentially, with an array (allocated dynamically) For this, we need a pointer to the data This choice should be irrelevant to a programmer using Vector We could change our minds later In fact, we will! Therefore, we need to provide an interface for the data read_element( ), write_element( ),...

Constructor In this class a constructor method becomes very important Our plan is to allocate some memory when a Vector object is created, in order to store the data The constructor should know the size of the Vector being created In this case, we make no default constructor (why?) As we will see, it's generally better to have one...

Constructor Vector::Vector(int size) { this -> size = size; this -> data = new double[size]; }

Using the constructor //in main program... int main( ){ Vector v1(5); Vector v2; //This does not compile!! } Why not add a default (parameter-less) constructor? Something else is missing here! Every new must be followed by a delete somewhere...

Default parameters One way to make a default constructor: write another function Better way: use default parameters on the constructor we have (in vector.h) public: Vector(int size=0); In case no parameter supplied: size=0 A default constructor is important! We may need to say new Vector[5]; //create 5 Vectors using the default constructor!

Destructor Back to the other thing that was missing... Vector::~Vector() { } /* For debugging cout << "Destructor called" << endl; cout << *this; */ delete [ ] data;

Why do I need a destructor? Every time we call the constructor (e.g. by declaring a Vector object) a new is executed. When the object goes out of scope, its memory is released (good!) But not the memory allocated inside the constructor It is our responsibility to clean this up!! To help us, C++ allows us to define a destructor function that will be automatically called.

When is the destructor called? When a local object goes out of scope: void f( ) { Vector v1(5); return; //this will call v1.~vector() before returning } Note: You cannot call ~Vector() directly...

Destructors and pointers Consider the following: Vector *vp = new Vector (5); delete vp; The last line will call the destructor on *vp and afterwards delete vp What does the last line do if we don't define a destructor? Destructor is called only if it exists...

Destructors and pointers Consider the following: Vector *vp = new Vector [5]; delete vp; What is the difference with previous slide? What is wrong?

Destructors and pointers Consider the following: Vector *vp = new Vector [5]; delete [ ] vp; The first line allocates memory for 5 Vectors The default constructor is called for each one This will not compile without a default constructor! The last line calls the destructor for each of the 5 Vectors Destructors are called in reverse order! (vp[4], then vp[3],...)

Summary Memory management is a non-trivial task that must be handled in the constructor/destructor Be careful! This can easily be done wrong! Usually, constructor allocates needed memory (new) and destructor frees all used memory (delete) We are not done! These tasks appear in many other places Copy constructor, operator=,...

Accessing elements Let's write a couple of easy methods: double Vector::read_element(int index) { return data[index]; } void Vector::write_element(int index, double e) { data[index] = e; } Can we add bounds checking to these? (Check if index<size)

Printing a Vector Let's overload the << operator ostream& operator<<(ostream & o, Vector &v) { for(int i=0; i<v.size; i++) o << v.read_element(i) << ", "; o << endl; } Recall: this function is a friend We are passing v as a ref, so the copy constructor is not needed This is a good idea... Note: we are using v.read_element(i), not v.data[i]. Why?

A simple program int main() { Vector v1(5); v1.write_element(0,1.1); v1.write_element(1,2.1); cout << v1; } Output?

Resizing Time to write a non-trivial method for our Vectors (Exercise!) void set_size(int newsize) This function should resize the vector If the new size is larger, we keep all the data Otherwise some data is thrown out We need to allocate appropriate new space and free the old data space

Resizing void Vector::set_size(int newsize) { double *newdata = new double[newsize]; for(int i=0; i<size && i<newsize ; i++) newdata[i] = data[i]; delete [ ] data; //Clean up!! data = newdata; size = newsize; return; }

Functions that use vectors Suppose that I want to find a function that calculates the sum of all elements of a vector double find_sum(vector v) 1-minute exercise: write this function Note: I don't need to pass the vector size as a parameter (unlike arrays)

Find Sum function double find_sum(vector v) { int i; double sum=0.0; for(i=0; i<v.get_size(); i++) sum += v.read_element(i); return sum; } Everyone happy?

A nasty bug The previous function contains a serious problem Vector v(3); v.write_element(0,1); v.write_element(1,2); v.write_element(2,3); cout << find_sum(v) << endl; cout << find_sum(v) << endl; The previous program crashes! Why?? Careful: a copy constructor is implicitly called

Another nasty bug Consider the following program: int main() { Vector v1(5); Vector v2(5); v2 = v1; } This program also crashes with the same error (double free) Why??

Explain the bugs What does v2 = v1 mean? Why does it even compile? Reminder: = means copy everything field-by-field The data field is copied This copies the pointer, not the data v2 and v1 are pointing to the same data Which is then freed twice at the end of scope! Added problem: memory leak on v2.data Same problem with parameter passing...

Overloading = Add the following to the class definition (vector.h) Vector & operator=(vector &); Explanation: we overload the = operator, so that it does something more sensible Parameter is ref to Vector (so that we don't have the same problem as in previous slides)

Overloading = Vector & Vector::operator=(Vector &v2) { int i; delete [ ] data; size = v2.size; data = new double[size]; for(i=0; i<size; i++) data[i] = v2.data[i]; }

Copy constructors One way to get around the problem with using Vector parameters is to use Vector & params. Another (less efficient) is to define a copy constructor: Add to vector.h Vector(Vector &); This method is automatically called when a vector is passed as a parameter

Copy constructor Vector::Vector(Vector &v2) { size = v2.size; data = new double[size]; int i; for(i=0; i<size; i++) data[i] = v2.data[i]; } Note: this is initially an empty object no delete

Using vectors more naturally One problem with read_element, write_element Too much typing! How about the following: Vector v1(5); v1[2] = 3.2; v1[3] = 4.5; Unfortunately, this does not compile! But we can fix it! Overload the [ ] operator!

Overloading [ ] What is the right prototype? What should we return? v[i] should be a double It should be able to appear on left-hand-side of = double & Add to vector.h double &operator[ ](int);

Overloading [ ] The implementation is very easy! double & Vector::operator[ ](int index) { return data[index]; }

An alternative implementation Why should we implement vector with an array? Let's do the same exercise again but with a linked list! Why? Practice. Also, this can be more efficient for some things (and less efficient for others)

A new class definition struct Node { int index; double data; struct Node * next; }; class Vector { int size; Node *head; public: Vector(int size=0); Vector(Vector &); ~Vector(); int get_size(); void set_size(int); double read_element(int); void write_element(int,double); double &operator[](int); Vector & operator=(vector &); friend ostream& operator<<(ostream &, Vector &); };

Outline Basic idea: store the data in a linked list Each node of the list contains an index,data pair Meaning: if the user tries to read an element not in the list, we return 0.0 save space for sparse vectors (with many 0s) Note: rest of interface is unchanged! User should be able to use this class in the same programs (ideally) without change Note2: size field is now not so important...

Constructor The constructor now doesn't need to do much but other methods will be more complicated Vector::Vector(int size) { this -> size = size; this -> head = 0; //No memory allocated }

Destructor The data is stored in a linked list (pointed to by head) When a vector is deleted, we need to delete the list Exercise: write a destructor that does this

Destructor: Vector::~Vector() { Node *tmp = head; while(tmp){ head = tmp->next; delete(tmp); tmp = head; } }

Copy constructor We want to create a new object with the same data as the old one We must copy the elements of the linked list one-by-one To make things easier, we don't care about the order of the list, just that all elements are copied Exercise: program the copy constructor

Copy constructor Vector::Vector(Vector &v2) { size = v2.size; head = 0; Node *tmp = v2.head; Node *tmp2; while(tmp){ //Data added in opposite order tmp2 = new Node; tmp2->index = tmp->index; tmp2->data = tmp->data; tmp2->next = head; head = tmp2; tmp = tmp->next; } }

Read/Write Element We want two methods that allow us to find a node of the linked list with a specific index (if it exists) The we read the data Or we change it If the node does not exist We return 0 Or we create it

Find Element To make the previous functions easier, write a helper function Node *find_element(int index, Node *head) Meaning: given a linked list (head) return the first node with the requested index. If none exists, return NULL (0) Exercise: program this

Find Element Node *find_element(int index, Node *head) { while(head){ if(head->index == index) return head; head = head->next; } return 0; }

Read Element Now read_element is easy double Vector::read_element(int index) { struct Node* tmp = find_element(index,head); if(tmp) return tmp->data; return 0; }

Write Element For write_element we have to add non-existing elements void Vector::write_element(int index, double e) { struct Node* tmp = find_element(index,head); if(tmp) tmp->data = e; else{ tmp = new Node; tmp -> index = index; tmp -> data = e; tmp -> next = head; head = tmp; } }

Easy parts The << operator still works! Because we wrote it using read_element() Could be optimized to run faster The = operator is almost identical to copy constructor!

The [ ] operator A design decision must be made for the [ ] operator What does it do if we try to access a non-existing index? Does it add it to the list? Does it simply return 0? But then, how can it return a double &? How will we be able to write on the returned element?

The [ ] operator This implementation adds to the list non-existing requested indices double & Vector::operator[ ](int index) { Node *tmp = find_element(index,head); if(tmp) return tmp->data; tmp = new Node; tmp -> index = index; tmp -> data = 0; tmp -> next = head; head=tmp; return tmp->data; }