Similar documents
static CS106L Spring 2009 Handout #21 May 12, 2009 Introduction

Chapter 17 vector and Free Store. Bjarne Stroustrup

Wentworth Institute of Technology COMP201 Computer Science II Spring 2015 Derbinsky. C++ Kitchen Sink. Lecture 14.

Short Notes of CS201

COSC 2P95 Lab 5 Object Orientation

CS201 - Introduction to Programming Glossary By

KOM3191 Object Oriented Programming Dr Muharrem Mercimek OPERATOR OVERLOADING. KOM3191 Object-Oriented Programming

Chapter 17 vector and Free Store

Chapter 17 vector and Free Store

Instantiation of Template class

THE NAME OF THE CONSTRUCTOR AND DESTRUCTOR(HAVING (~) BEFORE ITS NAME) FUNCTION MUST BE SAME AS THE NAME OF THE CLASS IN WHICH THEY ARE DECLARED.

Fast Introduction to Object Oriented Programming and C++

The vector Class and Memory Management Chapter 17. Bjarne Stroustrup Lawrence "Pete" Petersen Walter Daugherity Fall 2007

Ch. 12: Operator Overloading

Chapter 1 Getting Started

Vector and Free Store (Pointers and Memory Allocation)

G52CPP C++ Programming Lecture 13

Absolute C++ Walter Savitch

Abstract. Vector. Overview. Building from the ground up. Building from the ground up 1/8/10. Chapter 17 vector and Free Store

G52CPP C++ Programming Lecture 17

2 ADT Programming User-defined abstract data types

CS107 Handout 08 Spring 2007 April 9, 2007 The Ins and Outs of C Arrays

AN OVERVIEW OF C++ 1

Software Engineering Concepts: Invariants Silently Written & Called Functions Simple Class Example

4 Strings and Streams. Testing.

C++ Primer for CS175

Page. No. 1/15 CS201 Introduction to Programmming Solved Subjective Questions From spring 2010 Final Term Papers By vuzs Team


CS93SI Handout 04 Spring 2006 Apr Review Answers

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

nptr = new int; // assigns valid address_of_int value to nptr std::cin >> n; // assigns valid int value to n

Quiz Start Time: 09:34 PM Time Left 82 sec(s)

Assignment 1: grid. Due November 20, 11:59 PM Introduction

The Design Process. General Development Issues. C/C++ and OO Rules of Thumb. Home

CS201 Latest Solved MCQs

G52CPP C++ Programming Lecture 20

Evolution of Programming Languages

UEE1302 (1102) F10: Introduction to Computers and Programming

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

CSCI 102 Fall 2010 Exam #1

the gamedesigninitiative at cornell university Lecture 7 C++ Overview

CS 215 Fundamentals of Programming II Spring 2011 Project 2

Come and join us at WebLyceum

MARKING KEY The University of British Columbia MARKING KEY Computer Science 260 Midterm #2 Examination 12:30 noon, Thursday, March 15, 2012

(5 2) Introduction to Classes in C++ Instructor - Andrew S. O Fallon CptS 122 (February 7, 2018) Washington State University

CS11 Advanced C++ Fall Lecture 3

Operator overloading

G52CPP C++ Programming Lecture 16

C++\CLI. Jim Fawcett CSE687-OnLine Object Oriented Design Summer 2017

vector and Free Store

Pointers and Memory 1

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

Object Oriented Programming COP3330 / CGS5409

For Teacher's Use Only Q No Total Q No Q No

Lecture 8: Object-Oriented Programming (OOP) EE3490E: Programming S1 2017/2018 Dr. Đào Trung Kiên Hanoi Univ. of Science and Technology

Cpt S 122 Data Structures. Introduction to C++ Part II

Interview Questions of C++

Assertions and Exceptions

CS 251 INTERMEDIATE SOFTWARE DESIGN SPRING C ++ Basics Review part 2 Auto pointer, templates, STL algorithms

CS 11 C++ track: lecture 1

1/29/2011 AUTO POINTER (AUTO_PTR) INTERMEDIATE SOFTWARE DESIGN SPRING delete ptr might not happen memory leak!

University of Maryland Baltimore County. CMSC 202 Computer Science II. Fall Mid-Term Exam. Sections

Where do we go from here?

Module 7 b. -Namespaces -Exceptions handling

Programming Abstractions

VIRTUAL FUNCTIONS Chapter 10

1. Describe History of C++? 2. What is Dev. C++? 3. Why Use Dev. C++ instead of C++ DOS IDE?

Problem Solving with C++

Abstract Data Types (ADTs) 1. Legal Values. Client Code for Rational ADT. ADT Design. CS 247: Software Engineering Principles

CHAPTER 1 Introduction to Computers and Programming CHAPTER 2 Introduction to C++ ( Hexadecimal 0xF4 and Octal literals 031) cout Object

Ch. 11: References & the Copy-Constructor. - continued -

Programming. C++ Basics

A <Basic> C++ Course

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

A <Basic> C++ Course

CPSC 427: Object-Oriented Programming

PIC10B/1 Winter 2014 Exam I Study Guide

Introduction to Programming using C++

CIS 130 Exam #2 Review Suggestions

COP 3330 Final Exam Review

Lecture 8. Exceptions, Constructor, Templates TDDD86: DALP. Content. Contents Exceptions

Object-Oriented Programming

Copy Constructors and Assignment Operators

CS 247: Software Engineering Principles. ADT Design

Midterm Review. PIC 10B Spring 2018

CS201- Introduction to Programming Current Quizzes

Pointers, Dynamic Data, and Reference Types

class Array; // Class template declaration class Array public: // T="type",e.g.,int or float Array(int n); // Create array of n elements Array(); // C

21. Exceptions. Advanced Concepts: // exceptions #include <iostream> using namespace std;

IS 0020 Program Design and Software Tools

C++ PROGRAMMING LANGUAGE: DYNAMIC MEMORY ALLOCATION AND EXCEPTION IN C++. CAAM 519, CHAPTER 15

C++ Basics. Data Processing Course, I. Hrivnacova, IPN Orsay

CS3157: Advanced Programming. Outline

CSE 333. Lecture 9 - intro to C++ Hal Perkins Department of Computer Science & Engineering University of Washington

CS11 Intro C++ Spring 2018 Lecture 5

PIC 10A Objects/Classes

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

Vectors of Pointers to Objects. Vectors of Objects. Vectors of unique ptrs C++11. Arrays of Objects

Exercise 6.2 A generic container class

III. Classes (Chap. 3)

Transcription:

1 of 8 3/28/2010 8:03 AM C++ Special Topics Home Class Info Links Lectures Newsgroup Assignmen This is a short review of special topics in C++ especially helpful for various assignments. These notes are a quick summary. They do not replace the longer discussions in the textbook, though they may modify some. Constants in C++ Exceptions Memory allocation in C++ Streams and stringstreams Testing with stringstreams Overloading operators The iostream operators The arithmetic operators The assignment operator The relational operators Constants in C++ See Deitel, Sections 6.8, 7.4.3, and 10.7. In C, especially older C, constants were defined with #define PI 3.14159 The textbook rightly avoids these. Define constants in C++ with the const modifier, e.g., const double PI = 3.14159; It's a bit more complicated if you want to define class-level, i.e., static, constants. You declare them with static in the class declaration in the header file. You define them (no static) in the implementation file. For example, to get a class constant Circle::PI, you put this in circle.h, class Circle { public: static const double PI; ; This would go in circle.cpp: #include "circle.h" const double Circle::PI = 3.14159; Since the compiler doesn't see the value when compiling files that include circle.h, it can't completely optimize some code. Since this mostly affects integers, there's

2 of 8 3/28/2010 8:03 AM a special exception for them. You can declare their value in the header file. You still need to "define" them in the implementation file, but with no value. For example, to define integer constants Date::JANUARY, Date::FEBRUARY and so on, put this in date.h: class Date { public: static const int JANUARY = 0; static const int FEBRUARY = 1; ; and this in date.cpp: #include "date.h" const int Date::JANUARY; const int Date::FEBRUARY; Another kind of constant is the enumeration, e.g., enum { CLUB, DIAMOND, HEART, SPADE CardSuit; CardSuit suit = DIAMOND; This defines constants for the values 0, 1, 2 and 3, from left to right. Enumerations are also useful to label disconnected values, as in enum { SOCKET_ERROR = 32, ILLEGAL_URL = 45, ; In C++, an enumeration is not an int! It can be easily converted to int, as needed, but, like char, it's a distinct type. Exceptions See Deitel, Chapter 16, particularly the first 4 sections, for details. Also see the CPlusPlus page on exceptions. Signaling and handling errors can often make for complicated code. First, there's the signalling problem. If a function normally can return any number, what should it return if there's an error? Then, there's the handling problem. If there is a value that a function can return for an error, e.g., -1, then every piece of code that uses that function has to check for -1, and, probably, return -1 itself until eventually some outer function is reached that can respond to the problem, e.g., by asking the user for different input. These problems led to the invention of exceptions, which appear in C++ and other languages. The two key syntactic forms are throw and try-catch. throw is like a special kind of return. Throwing a value immediately exits every function that is being executed, until control returns to a try-catch block that is waiting for the type of data being thrown.

3 of 8 3/28/2010 8:03 AM In C++, you can throw anything. So, an easy thing is to use integers for error codes, and throw them when something bad is discovered somewhere. Most of your functions don't have to worry about error codes at all. They stay nice and simple. A function that discovers a problem just calls throw some integer. It doesn't have to worry about special return values. To handle the exception, when it occurs, you write top-level code like this: try { code that might, somewhere, way deep, throw an integer catch (int errorcode) { code to handle the exception; errorcode is the integer thrown A catch-clause is only executed if the exception is thrown. If the code inside the try doesn't throw an exception, the catch clause is ignored. In big programs, there will be many different kinds of possible exceptions, and you probably want to throw more information than just an error code. To do this, create an "exception" class. This can be any class, but it's most common to define subclasses of std::exception or one of its subclasses, such as std::runtime_error, which is defined in the header <stdexcept>. That way, you can handle them specially, if desired, or just catch them along with other exceptions, as shown here. To process different exceptions differently, use separate catch clauses for each type of exception you want to handle, like this: try { code can throw various exception objects catch (BadURLException &bue) { code for this case catch (HostNotFoundException &hnfe) { code for this case Memory allocation in C++ See Deitel Section 10.6. C has two functions, malloc and free, which dynamically allocate untyped blocks of memory. C++ uses new and delete, which are better for several reasons: Allocation and construction: Complex *cptr = new Complex(r, i); dynamically allocates memory for a new instance of Complex and calls to the constructor to initialize that memory, all in one call. Deallocation and destruction: delete cptr first calls the destructor for Complex, if any, then gives back the memory. That way, the destructor gets a chance to do additional cleanup, including other deletions, before the Complex object disappears. Be sure you know the difference between delete and delete[] and which

4 of 8 3/28/2010 8:03 AM one to use. Your program will crash otherwise. Be careful not to try and delete the same memory twice. Streams and string streams See Deitel, Section 18.12. Early programming languages used one set of functions to read and write to the console, and another set of functions to read and write to files. With the stream model, pioneered in Unix and C, there's a single set of functions that read from input streams and write to output streams. You write all your code to use these stream functions. You can then easily "redirect" your program's I/O as needed: To use console input and output, pass your code the pre-defined console streams cin and cout To use file input and output, create and pass your code file streams To use input from a string, and save all output in another string, create and pass your code string streams An istringstream is an input stream that gets characters from a string. For example, istringstream in("12 3 456"); int a, b, c; in >> a >> b >> c; CPPUNIT_ASSERT_EQUAL( 12, a ); CPPUNIT_ASSERT_EQUAL( 3, b ); CPPUNIT_ASSERT_EQUAL( 456, c ); defines an input stream with the characters a, space, b, space, c. An ostringstring is an output stream that sends characters to a string. For example, ostringstream out; out << 12 << " " << "abc"; creates an output string stream, and writes 12, space, and "abc" into it. out.str() will return whatever has been written into the output stream. See Section 18.12 for more examples. Testing with stringstreams Stringstreams are especially useful for testing code that reads and writes. It avoids making users enter data and read output, which is basically useless, and it avoids the need for auxiliary text files that are a pain to maintain. For example, if we had a Rational class that represented numbers like 1/2 and 22/7, and it was supposed to support reading and writing values in that form, we could test it like this: istringstream in("1/2 22/7"); Rational a, b; in >> a >> b;

5 of 8 3/28/2010 8:03 AM CPPUNIT_ASSERT_EQUAL( Rational(1, 2), a ); CPPUNIT_ASSERT_EQUAL( Rational(22, 7), b ); ostringstream out; out << a << " " << b; CPPUNIT_ASSERT_EQUAL( "1/2 22/7", out.str() ); Totally automated. No user action needed. Sweet! Overloading operators The book gives a fair number of examples of how to overload all the common (and not so common) operators. For a good readable introduction to this topic, see these notes from CalTech. The CalTech notes implement all operators as member functions. As a general rule, don't do this!. It leads to Less useful versions of operators such as + More code that depends on internal implementation details. Instead, where possible, define operators as global functions in the header of the class, after the class definition, like this: class Complex { bool operator<( const Complex &c1, const Complex &c2 ); Declare operators that need access to private class members as friends at the end of the class definition, like this: class Complex { friend Complex & operator+=( const Complex &c1, const Complex &c2 ); Declare the operators =, [], (), and ->, if needed, as member functions, because they need to return the class instance, like this: class Complex { Complex & operator=( const Complex &c ); Note that you only need to define assignment (and a copy constructor) if your class contains pointers to other data structures. Also note that member functions take one less argument. There's an implicit first argument in the this special variable.

6 of 8 3/28/2010 8:03 AM Different operators have hidden subtleties to be aware of. If you forget them, you'll get very confusing compiler errors: The iostream operators You need to overload at least << if you want to be able to use instances of your classes in code like this: CPPUNIT_ASSERT_EQUAL( Complex(-1, 0), Complex(0, 1) * Complex(0, 1) ); That's because the above expands into code that uses << to print the expected and actual values if the test fails. Remember: Both operators are binary operators. The first argument to both operators is the I/O stream. The stream must be passed by reference, so that it can be updated. The return value must be the stream, returned by reference, so that out lt;< x << y will work. The arithmetic operators If your class is going to support mutation operators like +=, then the general but unintuitive recommendation is to define += first, then use it to define +, not vice versa. This is discussed in the CalTech notes. (Again, ignore the fact that they make the operators member functions.) There is one small non-obvious refinement you can make for non-member definitions. For example, consider this definition of +: const MyClass operator+( const MyClass &a, const MyClass &b ) { MyClass c( a ); return c += b; This creates a copy of the first argument, increments it by the second argument, and returns it. But since we need a copy of the first argument, just pass it by value to begin with: const MyClass operator+( MyClass a, const MyClass &b ) { return a += b; The assignment operator If your class dynamically allocates pointers to other structures, you must define a destructor to deallocate them. If you define such a destructor, you must also define a copy constructor and the assignment operator. Otherwise, C++ will use the default definitions that create new instances with the same pointers. When one of those instance is destroyed, its destructor will delete the memory pointed, thereby invalidating the other instances. When they are used, or even just destroyed, your program will crash!

7 of 8 3/28/2010 8:03 AM Some key rules for writing assignment operators: If Class is your class, use the conventional form Class & operator=( Class &lhs, const Class &rhs) to define the operator. lhs and rhs refer to the left-hand side and right-hand side, respectively. Do not return const Class &, as shown in the book. The CalTech notes explain why. Check for self-assignment! This can happen more often than you think. Use the test this == &rhs. Always return *this. Allocate new copies for any data members that are dynamically allocated pointers. The relational operators You might think that if you overload == and <, then C++ should be able to figure out how to do the other relational operators, like!= and <= automatically. It can, sort of, but it doesn't do a very good job. The following in your header file: #include <utility> using namespace std::rel_ops; will define templated versions of the relational operators!=, <=, > and >=, using the obvious code, e.g., (simplified) template < class T > bool operator>( const T &x, const T &y ) { return y < x; Unfortunately, these templates only match when the two arguments have the same type. Assume your header includes #include <utility> using namespace std::rel_ops; // Code for rational number class class Rational { public: Rational( double n = 0, double d = 1 ) : numerator( n ), denominator( d ) { ; bool operator<( const Rational &r1, const Rational &r2); Then here's what will and won't work in client code: Rational r( 8, 3 ); CPPUNIT_ASSERT( Rational( 2 ) < r ); // OK CPPUNIT_ASSERT( 2 < r ); // OK, Rational( 2 ) called implicitly CPPUNIT_ASSERT( r > Rational( 2 ) ); // OK CPPUNIT_ASSERT( r > 2 ); // NOT OK, not same types So, for the current version of C++, using the standard libraries, if mixed comparisons are desired, you need to overload the 4 operators explicitly. Comments? Contact the Prof!

8 of 8 3/28/2010 8:03 AM