PIC 10A Objects/Classes

Similar documents
CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

CSE 303: Concepts and Tools for Software Development

PIC 10A Pointers, Arrays, and Dynamic Memory Allocation. Ernest Ryu UCLA Mathematics

Fast Introduction to Object Oriented Programming and C++

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

These are notes for the third lecture; if statements and loops.

Object Oriented Design

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

04-19 Discussion Notes

Ch. 12: Operator Overloading

Chapter 2 Basic Elements of C++

Chapter 10 Introduction to Classes

C++ Programming: From Problem Analysis to Program Design, Third Edition

PIC 20A The Basics of Java

Operator overloading

Lesson 13 - Vectors Dynamic Data Storage

Distributed Real-Time Control Systems. Lecture 17 C++ Programming Intro to C++ Objects and Classes

CE221 Programming in C++ Part 1 Introduction

Basic memory model Using functions Writing functions. Basics Prototypes Parameters Return types Functions and memory Names and namespaces

Welcome Back. CSCI 262 Data Structures. Hello, Let s Review. Hello, Let s Review. How to Review 8/19/ Review. Here s a simple C++ program:

PIC 10A Flow control. Ernest Ryu UCLA Mathematics

G52CPP C++ Programming Lecture 13

Announcements. CSCI 334: Principles of Programming Languages. Lecture 18: C/C++ Announcements. Announcements. Instructor: Dan Barowy

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

Outline. 1 Function calls and parameter passing. 2 Pointers, arrays, and references. 5 Declarations, scope, and lifetimes 6 I/O

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

Lecture 10: building large projects, beginning C++, C++ and structs

Introduction Of Classes ( OOPS )

CS 247: Software Engineering Principles. ADT Design

Week 2: Console I/O and Operators Arithmetic Operators. Integer Division. Arithmetic Operators. Gaddis: Chapter 3 (2.14,3.1-6,3.9-10,5.

Variables. Data Types.

Understanding main() function Input/Output Streams

COMP322 - Introduction to C++ Lecture 01 - Introduction

Welcome Back. CSCI 262 Data Structures. Hello, Let s Review. Hello, Let s Review. How to Review 1/9/ Review. Here s a simple C++ program:

ADTs & Classes. An introduction

Computing and Statistical Data Analysis Lecture 3

Shahram Rahatlou. Computing Methods in Physics. Overloading Operators friend functions static data and methods

COMP322 - Introduction to C++ Lecture 02 - Basics of C++

Implementing an ADT with a Class

Makefiles Makefiles should begin with a comment section of the following form and with the following information filled in:

04-05 Discussion Notes

Reference Parameters A reference parameter is an alias for its corresponding argument in the function call. Use the ampersand (&) to indicate that

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

CS3157: Advanced Programming. Outline

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

W3101: Programming Languages C++ Ramana Isukapalli

SFU CMPT Topic: Classes

UEE1302 (1102) F10: Introduction to Computers and Programming

QUIZ Friends class Y;

Starting to Program in C++ (Basics & I/O)

Function Overloading

The issues. Programming in C++ Common storage modes. Static storage in C++ Session 8 Memory Management

Programming Abstractions

C++ Mini-Course. Part 1: Mechanics Part 2: Basics Part 3: References Part 4: Const Part 5: Inheritance Part 6: Libraries Part 7: Conclusion. C Rulez!

Variables and Constants

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

Lecture 18 Tao Wang 1

AN OVERVIEW OF C++ 1

CIS 190: C/C++ Programming. Classes in C++

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

EL2310 Scientific Programming

QUIZ. What is wrong with this code that uses default arguments?

CS 376b Computer Vision

A brief introduction to C++

III. Classes (Chap. 3)

y

Programming C++ Lecture 6. Howest, Fall 2013 Instructor: Dr. Jennifer B. Sartor

COMP322 - Introduction to C++

the gamedesigninitiative at cornell university Lecture 7 C++ Overview

CSE 333. Lecture 11 - constructor insanity. Hal Perkins Paul G. Allen School of Computer Science & Engineering University of Washington

GE U111 Engineering Problem Solving & Computation Lecture 6 February 2, 2004

Classes: A Deeper Look

Chapter 2. Procedural Programming

2 ADT Programming User-defined abstract data types

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

Object-Oriented Principles and Practice / C++

Programmazione. Prof. Marco Bertini

C++ Support Classes (Data and Variables)

Object Oriented Design

Financial computing with C++

Computer Science II Lecture 1 Introduction and Background

4. Structure of a C++ program

Classes in C++98 and C++11

Object-oriented Programming in C++

Introduction to C++ Professor Hugh C. Lauer CS-2303, System Programming Concepts

Object-Oriented Programming

LECTURE 02 INTRODUCTION TO C++

MARKING KEY The University of British Columbia MARKING KEY Computer Science 260 Midterm #1 Examination 12:30 noon, Tuesday, February 14, 2012

CS24 Week 3 Lecture 1

Sixth lecture; classes, objects, reference operator.

6.096 Introduction to C++

Objectives. Chapter 2: Basic Elements of C++ Introduction. Objectives (cont d.) A C++ Program (cont d.) A C++ Program

Chapter 2: Basic Elements of C++

C++ Review. CptS 223 Advanced Data Structures. Larry Holder School of Electrical Engineering and Computer Science Washington State University

CSE 333. Lecture 10 - references, const, classes. Hal Perkins Paul G. Allen School of Computer Science & Engineering University of Washington

Chapter 2: Basic Elements of C++ Objectives. Objectives (cont d.) A C++ Program. Introduction

Types, Values, Variables & Assignment. EECS 211 Winter 2018

CSCI-1200 Data Structures Spring 2018 Lecture 8 Templated Classes & Vector Implementation

Programming. Computer. Program. Programming Language. Execute sequence of simple (primitive) instructions What instructions should be provided?

Annotation Annotation or block comments Provide high-level description and documentation of section of code More detail than simple comments

Transcription:

PIC 10A Objects/Classes Ernest Ryu UCLA Mathematics Last edited: November 13, 2017

User-defined types In C++, we can define our own custom types. Object is synonymous to variable, and class is synonymous to type. The words variable and type connote the subject is a built-in type. The words object and class connote the subject is a user-defined type. Object oriented programming is the style of programming that focuses around objects. 2

Struct A struct is a user-defined composite type. It is a collection of data members. struct student { string firstname ; string lastname ; int UID ; ; This example has 3 data members. 3

Member access operator The member access operator. is used to access members of a struct. int main () { student s1; s1. firstname = " Ernest "; s1. lastname = " Ryu "; s1. UID = 123456789 ; student s2 = s1; s2. firstname = " Elizabeth "; s2. UID = 123456780 ; cout << s2. firstname << " " << s2. lastname << " has UID " << s2. UID << endl ; The output is Elizabeth Ryu has UID 123456780 4

Struct You can view a struct as a chunk of data. It s more convenient to use student s1 than to use string s1firstname, string s1lastname, and int s1uid separately. structs are the precursors of classes. structs are C-style while classes are C++-style. 5

Class A class is a more sophisticated, C++-style struct. You declare classes with class class_name { public: data members; member functions; ; For the moment, don t worry about the public keyword. 6

Syntax warning: semicolon after class You need a semicolon at the end of struct and class definitions. struct student { ; class complex { ; Don t forget the semicolon. 7

Data members Data members, also called fields, of a class are just like data members of a struct. class complex { public : double real, imag ; ; (The C++ standard library complex provides a complex number class, but we ll create our own.) 8

Member functions classes can also have member functions, also called methods. class complex { public : double real, imag ; void disp () { // a member function cout << real << " +" << imag << " i" << endl ; ; 9

Member functions Access member functions with the member access operator. int main () { complex c1; c1. real = 0.1 ; c1. imag = 2; c1. disp (); // output 0.1+2 i 10

Member functions You can declare and define member functions separately. class complex { public : double real, imag ; void disp (); // declaration ; void complex :: disp () { // definition cout << real << " +" << imag << " i" << endl ; In the definition, refer to the function name with classname::funcname. 11

Member functions Member functions have access to data members of the object it belongs to. Member functions often cause side effects through modifying data members. :: is the scope resolution operator. We will discuss it is more detail when we talk about namespaces. You can view classes as the collection of data members accompanied by useful member functions. 12

Member functions with return values Member functions, like any function, can have return values. class complex { public : double real, imag ; void disp (); double magnitude (); ; double complex :: magnitude () { return sqrt ( real * real + imag * imag ); int main () { complex c1; c1. real = 3; c1. imag = 4; cout << c1. magnitude () << endl ; // output 5 13

Member functions with return values The return type of an member function can be the class itself. class complex { public : double real, imag ; complex add ( complex a); ; complex complex :: add ( complex a) { complex val ; val. real = real + a. real ; val. imag = imag + a. imag ; return val ; 14

Member functions with return values Let s see how to use a member function int main () { complex c1; c1. real = 1.1 ; c1. imag = 0; complex c2; c2. real = 2.2 ; c2. imag = 1.2 ; complex c3 = c1.add (c2 ); c3. disp (); // output 3.3+1.2 i cout << typeid (c1.add (c3 )). name () << endl ; // output class complex (c1.add (c3 )). disp () // output 4.4+1.2 i 15

this pointer The this pointer is a pointer of type class_name* and it points to the object the member function belongs to. class complex { public : complex add ( complex a); complex add_ equals ( complex a); ; complex complex :: add_ equals ( complex a) { * this = add (a); return * this ; 16

this pointer int main () { complex c1; c1. real = 1.1 ; c1. imag = 0; complex c2; c2. real = 2.2 ; c2. imag = 1.2 ; c1. add_equals (c2 ); c1. disp (); // output 3.3+1.2 i 17

Constructor The following initialization is a bit cumbersome. complex c1; c1. real = 1.1 ; c1. imag = 0.2 ; Use constructors to simplify initialization. 18

Construtor A constructor is called when the object is created. class complex { public : // a constructor with 2 inputs complex ( double r, double i); ; int main () { complex c1(1.1, 0.2 ); c1. disp (); // output 1.1+0.2 i complex :: complex ( double r, double i) { real = r; imag = i; // constructor definition Declaration and initialize together with a constructor. 19

Default constructor When an object is created with no inputs, default constructor is called. class complex { public : complex (); // default constructor complex ( double r, double i); ; int main () { complex c1; // default constructor called complex :: complex () { // do nothing 20

Implicitly defined default constructor When no constructors are provided, the compiler implicitly defines a trivial default constructor. The trivial default constructor does nothing. 21

So the class Implicitly defined default constructor class complex { public : double real, imag ; void disp (); ; void complex :: disp () { is the same class as class complex { public : double real, imag ; complex (); // default constructor void disp (); ; void complex :: disp () { complex :: complex () { // trivial default constr 22

Implicitly defined default constructor However, the class class complex { public : double real, imag ; void disp (); complex ( double r, double i); ; void complex :: disp () { complex :: complex ( double r, double i) { does not have a default constructor. 23

Do you need the default constructor? You need the default constructor if you plan to use arrays of the class. int main () { // default constr called for all 10 objects complex c_arr [10 ]; // pointer to an object of class complex complex * c_p ; // default constr called for all 20 objects c_p = new complex [ 20 ]; delete [] c_p ; 24

Constructors Often it makes sense to have several constructors. class complex { public : double real, imag ; complex (); complex ( double r); complex ( double r, double i); ; complex :: complex () { complex :: complex ( double r) { real = r; imag = 0.0 ; complex :: complex ( double r, double i) { real = r; imag = i; 25

Type conversion Type casting an object of class T1 into an object of class T2 is really just calling a constructor. class complex { public : double real, imag ; complex (); complex ( double r); // this constructor called complex ( double r, double i); ; int main () { (( complex ) 2.2 ). disp (); // output 2.2+0 i 26

Type conversion Think of double d1 = static_ cast < double >( 2); as calling double :: double ( int i) { On the other hand, string s = string ( a ); // error fails because there is no constructor that looks like string :: string ( char c) { 27

Type conversion In the pointers lecture, I said the cast from T1 to T2 succeeds if there is a suitable way. The suitable way is a constructor. If there is a constructor with signature T2(T1 it is called. t); If there is a constructor that can be called after implicit conversion, it is called. For example, int i = 5; complex c1 = complex ( i); // calls complex ( double d); Otherwise the compiler fails. 28

Function style cast You can have multiple inputs when using the function style cast. complex ( 2.2,0.3 ). disp (); // output 2.2+0.3 i cout << typeid ( complex (0,0 )). name () << endl ; // output class complex complex c1( 0.0, -0.1 ); // object has name c1 View the function style cast as directly calling the constructor without giving a name to the object. 29

Initializing objects with style There s often more than 1 way to initialize an object. // call 1 constructor complex c1(1.2,2.2 ); This is shorter and faster. // call 2 constructors and then copy complex c2 = complex ( 1.2, 2.2 ); This is more readable and therefore is in better style. 30

Syntax warning: default constructor When calling the default constructor, don t use parentheses. complex c1; // default constr complex c2( 2.2 ); // non - default constr complex c3( 2.2, 3.3 ); // non - default constr // c4 is a func with no inputs // and return type complex ( declared not defined ) complex c4 (); c4. disp (); // error. c4 is a function This is terrible, but it s just how C++ is. 31

Syntax warning: default constructor When using new, you may or may not use parentheses to call the default constructor. complex * c1 = new complex ; // default constr complex * c2 = new complex (); // default constr complex * c3 = new complex ( 2.2 ); // non - default complex * c4 = new complex ( 2.2,3.3 ); // non - default delete c1; delete c2; delete c3; delete c4; When T is a class, new T and new T() are (almost) the same: they both call the default constructor. 32

Syntax warning: default constructor When directly calling constructors through function style casts, you must use parentheses to call the default constructor. complex (). disp (); // undefined output complex ( 2.2 ). disp (); // output 2.2+0 i complex ( 2.2,3.3 ). disp (); // output 2.2+3.3 i complex. disp (); // error ( complex ). disp (); // error 33

Private members Private data members or member functions can only be accessed by member functions of the object. Public data members or member functions can be accessed from the outside as well. class complex { private : double real, imag ; public : complex ( double r, double i); void setreal ( double r) { real = r; double getreal () { return real ; ; int main () { complex c1(2.2,3.5 ); c1. real = 1.2 ; // error 34

Private data members By making data members private, user must interact with the them through the provided public methods. This forces the user to use the object in a certain way. In C++, data members are more often private than public. When data members are public, users can directly write to them. This is not safe. The class complex doesn t really benefit from private data members. The classes in hw8 do benefit from private data members. 35

Private member functions Member functions can also be private. You can t call a private member function from the outside. I.e., you can t do c1. disp (); if disp is private. Helper functions are functions intended to aid other functions but not intended to be used by themselves. Helper functions should be private. 36

Why private? Achieve modular programming by hiding as much information as possible (by making members private). A well-written class provides a simple interface to the user while hiding its complex inner workings. Control how to use the class through providing certain public members and hiding certain members by making them private, This restriction makes it more likely for the user to use the object exactly as intended. Bugs are less likely this way. 37

Operator overloading Operators are overloaded functions, and we can overload them ourselves. Most operators (e.g. +, =, &&, <<, new, delete) can be overloaded. Only overload what you need. (Overloading < for class complex makes no sense.) Some operators (e.g.., ::) cannot be overloaded. 38

operator+ class complex { public : complex ( double r, double i); complex operator +( complex a); void disp (); ; int main () { complex c1(2.2, 3.3 ), c2(0.8, 1); (c1+c2 ). disp (); // output 3+4.3 i complex complex :: operator +( complex a) { return complex ( real +a.real, imag +a. imag ); 39

operator+= class complex { public : complex ( double r, double i); complex operator +( complex a); complex operator +=( complex a); ; complex complex :: operator +=( complex a) { return complex ( real +=a.real, imag +=a. imag ); // return * this = * this + a; // return * this = operator +( a); (There are several ways to write operator+=.) 40

operator- and operator- There are 2 operator-s: the unary - multiplies by -1 while the binary - subtracts. class complex { public : complex operator -(); // unary - complex operator -( complex a); // binary - ; int main () { complex c1(1.2,0.3 ), c2(0,0); complex c3; c3 = - c1; // unary - called c3 = c1 - c2; // binary - called 41

operator- and operatorcomplex complex :: operator -() { return complex (-real,- imag ); complex complex :: operator -( complex a) { return complex (real -a.real,imag -a. imag ); 42

operator== class complex { public : bool operator ==( complex a); ; bool complex :: operator ==( complex a) { return ( real ==a. real ) && ( imag ==a. imag ); 43

When should you use operator overloads? Only use operator overloads when the meaning is completely clear. Actually classes that benefit from operator overloads are somewhat rare. Nevertheless, you need to know them, because the standard library heavily relies on them. In C++, you learn certain topics not because you ll likely use them but rather because libraries use them. Being good at C++ involves getting comfortable with reading and using libraries. 44

namespace The using-directive using namespace std ; means we re using all names within the namespace std. Really, the full name of cout is std::cout. The full name uses the scope resolution operator :: to specify which namespace cout is in. Avoid name conflicts with namespaces. (Just as you would use full names to distinguish an Alice from another Alice.) 45

namespace # include <cmath > // using namespace std ; namespace mymath { double sqrt ( double x) { int main () { double d = 9; cout << std :: sqrt (d); // sqrt from cmath cout << mymath :: sqrt ( d); // sqrt from mymath 46

using-directive The using-directive using namespace std ; makes all names in std accessible without explicitly referring to its namespace. I.e., it allows you to do string s; instead of std :: string s; 47

using-declaration The using-declaration individually specifies the names to be used without referring to their namespaces. # inclue < iostream > # include < string > using std :: cout ; using std :: endl ; using std :: string ; int main () { string s = " Good morning." cout << s << endl ; 48

namespace namespaces are helpful in organizing a large code base. (When 100 programmers are working together, naming conflicts will happen.) The using-directive using namespace std ; is bad style. It bypasses the safety namespaces provide, and you may unintentionally use a library feature you didn t know existed. It s safer to individually specify the library features you wish to use with using-declarations. 49

#include guards When a codebase gets larger, you often include a single header file multiple times. In hw8, main.cpp contains # include " card.h" # include " deck.h" However, deck.h contains # include " card.h" So card.h is #incuded multiple times in main.cpp. This causes a compile-time error. 50

#include guards #include guards remedy this issue. card.h should contain # ifndef CARD_H # define CARD_H # include class card { ; # endif // CARD_H 51

#include guards # ifndef CARD_ H // if not defined # define CARD_H # endif // CARD_H 1. The first time card.h is #included, CARD_H is not defined. 2. CARD_H is defined. 3. The header file makes the declarations. 4. #endif matches the #ifndef 5. The second time card.h is #included, CARD_H is defined. So all code until #endif is ignored. 52

#pragma once The preprocessor directive #pragma directs the compiler to use certain non-standard features. (So portability can be an issue.) #pragma once tells the compiler to #include the header file only once. I.e., it does the job of #include guard. # pragma once class something { ; #pragma once is easier and less error-prone than #include guards. #pragma once is non-standard, but most compilers (e.g. Clang, GCC(g++), and MS Visual C++) support it. In HW8, you will use #pragma once. In HW9, you will use explicit #include guards. 53

Non-member functions Some functions make more sense as non-member functions class complex { ; // Non - member functions complex exp ( complex c) { double r = c. real * cos (c. imag ); double i = c. real * sin (c. imag ); return complex (r,i); Declare and define such functions in the files that declare and define the class, respectively. Header files should be a nice package; if it provides a class, accopany it with useful member and non-member functions. 54

Returning references Just as you can get inputs by copy and by reference, you can also return by copy and by reference. Actually, we re not really ready to talk about this topic. (We need to know about copy constructors an destructors.) However, standard library functions do return references when appropriate. So you ll need to at least vaguely understand this topic to read C++ standard library documentation. 55

Returning references: example Why does this work? int i = 0; ++++ i; cout << i << endl ; // output 2 This works because the return value of operator++ is int&. int & int :: operator ++() { * this = * this + 1; // increment the int return * this ; // return reference to * this 56

Implicitly defined operator= The compiler implicitly defines the copy assignment operator = if you don t provide your own. I.e., the compiler defines T& operator =( RHS T) { // copy all data members of T // into data members of * this return * this ; automatically for class T. 57

Implicitly defined operator= Because operator= returns a reference and not a copy, you can do int & int :: operator ++() { return * this = * this + 1; The compound assignment operators +=, -=, *=, etc. also return references. So you can do int & int :: operator ++() { return * this += 1; 58

Implicitly defined operator= For our class complex we can do class complex { public : complex operator +( complex a) { return complex ( real + a.real, imag + a. imag ); // complex & operator =( complex a) { // real = a. real ; imag = a. imag ; // return * this ; // complex & operator +=( complex a) { return (* this = * this + a); 59

cout and operator<< std::cout is a global variable of class std::ostream. The operator << is overloaded for many classes within the standard library. We can overload it for our custom classes. class complex { ; // Non - member operator overload std :: ostream & operator < <( std :: ostream & s, complex c) { return s << c. real << "+" << c. imag << "i"; using std :: cout ; int main () { complex c1(1.1,2.2 ); cout << c1 <<"\n"; // output 1.1+2.2 i 60

cout and operator<< You can do void operator < <( ) { and this will allow cout << c1; However, you need to return the reference to allow chaining cout << c1 << " hello \n"; // same as ( ( cout << c1) << " hello \n" ); (std::endl is a function pointer and we won t talk about it.) 61

cout and operator<< If you return a copy and not a reference std :: ostream operator < <( ) { you get a compilation error. (The iostream library prevents you from doing this.) Returning a copied object of class std::ostream wouldn t make sense anyways. What would a copy of std::cout mean? 62

Default inputs You can specify default inputs or default arguments in your function declaration. class complex { public : complex ( double r, double i = 0); ; // i = 0 not repeated complex :: complex ( double r, double i) { real = r; imag = i; Don t repeat the specification in the function definition. You can have default arguments in any function. 63

Member initializer list In defining constructors, you can use the member initializer list to initialize data members. complex :: complex ( double r, double i) : real (r), imag (i) { The member initializer list is convenient, but sometimes its more than just syntactic sugar. Without the member initializer list, default constructors of members are first called and then the assignment happens. (Sometimes this is wasteful. If there s no default constructor this is infeasible.) With the member initializer list you can choose which constructor to call. 64

Struct vs. classes I ve said a struct is a collection of its data members, and a class is collection of its (usually private) data members accompanied by member functions. That is indeed how people view and use structs. But really, there s only one small difference: by default, members of classes are private while members of structs are public. So structs can have private data members and member functions, but then there s no reason to call is a struct. By convention, people expect structs to be just data. It s good style to respect this convention. 65