References Revisited CSE 333 Autumn 2018

Slides:



Advertisements
Similar presentations
1 CSE 303 Lecture 21 Classes and Objects in C++ slides created by Marty Stepp
Advertisements

CSE 332: C++ program structure and development environment C++ Program Structure (and tools) Today we’ll talk generally about C++ development (plus a few.
CSE 332: C++ Overloading Overview of C++ Overloading Overloading occurs when the same operator or function name is used with different signatures Both.
Review for Midterm Chapter 1-9 CSc 212 Data Structures.
C++ Memory Overview 4 major memory segments Key differences from Java
Current Assignments Start Reading Chapter 6 Project 3 – Due Thursday, July 24 Contact List Program Homework 6 – Due Sunday, July 20 First part easy true/false.
Midterm Review CS1220 Spring Disclaimer The following questions are representative of those that will appear on the midterm exam. They do not represent.
CSE 332: C++ template examples Concepts and Models Templates impose requirements on type parameters –Types that are plugged in must meet those requirements.
CS 11 C++ track: lecture 3 Today const and const -correctness operator overloading.
System Programming Practical Session 7 C++ Memory Handling.
CSE 332: C++ template examples Today: Using Class and Function Templates Two examples –Function template for printing different types –Class template for.
1 Introduction to Object Oriented Programming Chapter 10.
C++ Namespaces, Exceptions CSci 588: Data Structures, Algorithms and Software Design All material not from online sources copyright © Travis Desell, 2011.
CS 342: C++ Overloading Copyright © 2004 Dept. of Computer Science and Engineering, Washington University Overview of C++ Overloading Overloading occurs.
CSE 332: C++ Overloading Overview of C++ Overloading Overloading occurs when the same operator or function name is used with different signatures Both.
1 Another Example: Complex Class #ifndef _Complex_H #define _Complex_H class Complex { float re, im; // by default private public: Complex(float x = 0,
1 Ugly Realities The Dark Side of C++ Chapter 12.
Pointer to an Object Can define a pointer to an object:
Overview 4 major memory segments Key differences from Java stack
Eugene Hsu.
Command Line Arguments
Chapter 1-4 CSc 212 Data Structures, Sec AB CCNY, Spring 2012
This pointer, Dynamic memory allocation, Constructors and Destructor
The dirty secrets of objects
C++ References, Const, Classes CSE 333 Spring 2018
C++ Intro CSE 333 Spring 2018 Instructor: Justin Hsia
C++ Constructor Insanity CSE 333 Spring 2018
Overview 4 major memory segments Key differences from Java stack
C++ Templates CSE 333 Spring 2018
C++ Encapsulation, Heap CSE 333 Spring 2018
Overview of Memory Layout in C++
Brought to you by C++ Tutorial Brought to you by
Overview of C++ Overloading
C++ STL, Smart Pointers Intro CSE 333 Spring 2018
C++ Smart Pointers CSE 333 Spring 2018
References Revisited CSE 333 Spring 2018
References Revisited CSE 333 Summer 2018
Server-side Programming CSE 333 Autumn 2018
C++ Inheritance II, Casting CSE 333 Summer 2018
C++ Smart Pointers CSE 333 Autumn 2018
C++ Templates CSE 333 Summer 2018
Course Wrap-Up CSE 333 Autumn 2018
C++ Class Details, Heap CSE 333 Autumn 2018
C++ Constructor Insanity CSE 333 Summer 2018
C++ Standard Template Library CSE 333 Autumn 2018
C++ Class Details, Heap CSE 333 Summer 2018
C++ Inheritance I CSE 333 Autumn 2018
C++ Intro CSE 333 Autumn 2018 Instructor: Hal Perkins
Client-side Networking CSE 333 Autumn 2018
C++ Standard Template Library CSE 333 Winter 2019
C++ Templates CSE 333 Autumn 2018
C++ Constructor Insanity CSE 333 Autumn 2018
C++ Class Details, Heap CSE 333 Winter 2019
Concurrency: Processes CSE 333 Autumn 2018
Pointers and dynamic objects
C++ Constructor Insanity CSE 333 Winter 2019
C++ Smart Pointers CSE 333 Winter 2019
Client-side Networking CSE 333 Winter 2019
References Revisited CSE 333 Winter 2019
C++ Inheritance I CSE 333 Winter 2019
Low-Level I/O – the POSIX Layer CSE 333 Winter 2019
C++ Templates CSE 333 Winter 2019
Concurrency: Processes CSE 333 Winter 2019
C++ Class Details, Heap CSE 333 Spring 2019
Templates CMSC 202, Version 4/02.
C++ Constructor Insanity CSE 333 Spring 2019
Final C Details CSE 333 Autumn 2018
C++ Standard Template Library CSE 333 Spring 2019
Chapter 1-4 CSc 212 Data Structures, Sec FG CCNY, 2009
SPL – PS3 C++ Classes.
Presentation transcript:

References Revisited CSE 333 Autumn 2018 Instructor: Hal Perkins Teaching Assistants: Tarkan Al-Kazily Renshu Gu Travis McGaha Harshita Neti Thai Pham Forrest Timour Soumya Vasisht Yifan Xu

5/2/2018 Administrivia No exercise due Friday. Next exercise out Friday after midterm, due Monday before class (smart ptr exercise) Midterm: Friday in class Closed book, no notes Old exams and topic list on the course web now Everything up through C++ classes, dynamic memory, templates & STL Review in sections tomorrow Homework 3 – spec out now, files pushed by Friday Spec overview & demo in class today In hw3 directory: make ./test_suite cd hw3fsck/ cd .. ./buildfileindex test_tree/enron_email/ /tmp/enron.idx hw3fsck/hw3fsck /tmp/enron.idx ./filesearchshell /tmp/enron.idx ls -l unit_test_indices/ ./filesearchshell unit_test_indices/*

∃ Confusion About References When should they be used? Particularly with parameters and return values When can using them cause trouble?

The Plan… We’ll go through a bunch of code examples For each example, we want to decide if it is appropriate to use references, and then chose one answer from this list: A. We must NOT use a reference B. It’s OK but discouraged to use a reference C. It’s OK and encouraged to use a reference D. We must use a reference E. We’re lost…

Parameters 1 param1.cc #include <cstdlib> 5/2/2018 Parameters 1 param1.cc #include <cstdlib> #include <iostream> using namespace std; // SHOULD WE BE USING REFERENCES FOR PARAMETERS "a" AND "b"? // (Answer: ?) int LeastCommonMultiple(const int &a, const int &b) { for (int n=1; ; n++) { if ((n % a == 0) && (n % b == 0)) return n; } int main(int argc, char **argv) { int x = 12, y = 14; int lcm = LeastCommonMultiple(x, y); cout << "LCM(" << x << "," << y << ") is " << lcm << endl; return EXIT_SUCCESS;

param1.cc B. It’s OK but discouraged to use a reference A const reference to a small primitive type (e.g. int, float) We aren’t changing the argument values (const), so it doesn’t matter if we use a copy or not – reference is optional Correct behavior, but might have better performance with regular call-by-value

Parameters 2 param2.cc #include <cmath> #include <cstdlib> 5/2/2018 Parameters 2 param2.cc #include <cmath> #include <cstdlib> #include <iostream> #include "ThreeDPoint.h" // SHOULD WE BE USING REFERENCES FOR PARAMETERS "a" AND "b"? // (Answer: ?) double Distance(const ThreeDPoint &a, const ThreeDPoint &b) { double dist = pow(a.x-b.x,2) + pow(a.y-b.y,2) + pow(a.z-b.z,2); return sqrt(dist); } int main(int argc, char **argv) { ThreeDPoint a(1,2,3), b(4,5,6); int dist = Distance(a, b); cout << "Distance(a,b) is " << dist << endl; return EXIT_SUCCESS;

param2.cc C. It’s OK and encouraged to use a reference A const reference to a complex type (e.g. struct, object instance) We aren’t changing the argument values (const), so it doesn’t matter if we use a copy or not – reference is optional Correct behavior and likely performance benefit from not having to copy Follow-up: Why not pass in a pointer instead?

Return Value 1 ret1.cc #include <cstdlib> 5/2/2018 Return Value 1 ret1.cc #include <cstdlib> #include <iostream> typedef struct Point_st { double x, y, z; } Point; // SHOULD WE BE USING A REFERENCE FOR THE RETURN VALUE? // (Answer: ?) Point &MakePoint(const int x, const int y, const int z) { Point retval = {x, y, z}; return retval; } int main(int argc, char **argv) { Point p = MakePoint(1, 2, 3); std::cout << p.x << "," << p.y << "," << p.z << std::endl; return EXIT_SUCCESS;

ret1.cc A. We must NOT use a reference 5/2/2018 ret1.cc A. We must NOT use a reference A reference to a stack-allocated complex type Never return a reference (or pointer to) a local variable Also, destructor is called on object when returning

Copy Constructor Complex1.h #ifndef _COMPLEX_H_ #define _COMPLEX_H_ 5/2/2018 Copy Constructor Complex1.h #ifndef _COMPLEX_H_ #define _COMPLEX_H_ #include <iostream> namespace complex { class Complex { public: // Copy constructor -- should we pass a reference or not? // (Answer: ?) Complex(const Complex &copyme) { real_ = copyme.real_; imag_ = copyme.image_; } private: double real_, imag_; }; // class Complex } // namespace complex #endif // _COMPLEX_H_

Complex1.h D. We must use a reference 5/2/2018 Complex1.h D. We must use a reference A const reference to a complex type We aren’t changing the argument’s values so it doesn’t matter if we use a copy or not, in theory A copy constructor must take a reference, otherwise it would need to call itself to make a (call-by-value) copy of the argument…

operator+ Complex2.h #include <iostream> namespace complex { 5/2/2018 operator+ Complex2.h #include <iostream> namespace complex { class Complex { public: // Should operator+ return a reference or not? // (Answer: ?) Complex &operator+(const Complex &a) const { Complex tmp(0,0); tmp.real_ = this->real_ + a.real_; tmp.imag_ = this->imag_ + a.imag_; return tmp; } private: double real_, imag_; }; // class Complex } // namespace complex

Complex2.h A. We must NOT use a reference 5/2/2018 Complex2.h A. We must NOT use a reference A reference to a stack-allocated variable Never return a reference (or pointer to) a local variable Destructor is also called on object when returning Follow-up: If we fix the code, does chaining work?

Assignment Operator Complex3.h #include <iostream> 5/2/2018 Assignment Operator Complex3.h #include <iostream> namespace complex { class Complex { public: // Should the assignment operator return a reference? // (Answer: ?) Complex &operator=(const Complex &a) { if (this != &a) { this->real_ = a.real_; this->imag_ = a.imag_; } return *this; private: double real_, imag_; }; // class Complex } // namespace complex

Complex3.h D. We must use a reference 5/2/2018 Complex3.h D. We must use a reference A reference to *this, the object this method was called on All of the “work” is done in the method body; the return value is only there for chaining (but required for chaining to work correctly) Follow-up: What happens in (a = b) = c; if we don’t use a reference? Does it compile? Does it “work”? Does it do the “right thing”?

operator+= Complex4.h #include <iostream> namespace complex { 5/2/2018 operator+= Complex4.h #include <iostream> namespace complex { class Complex { public: // Should += return a reference? // (Answer: ?) Complex &operator+=(const Complex &a) { this->real_ += a.real_; this->imag_ += a.imag_; return *this; } private: double real_, imag_; }; // class Complex } // namespace complex

Complex4.h D. We must use a reference 5/2/2018 Complex4.h D. We must use a reference A reference to *this, the object this method was called on All of the “work” is done in the method body; the return value is only there for chaining (but required for chaining to work correctly) You hardly see people chain +=, but it is allowed by the primitive data types, so we follow suit Style/code quality: overloaded operators should have similar semantics to basic definitions to avoid programmer surprises

operator<< Complex5.h #include <iostream> 5/2/2018 operator<< Complex5.h #include <iostream> namespace complex { class Complex { public: double real() const { return real_; }; double imag() const { return imag_; }; private: double real_, imag_; }; // class Complex } // namespace complex // Should operator<< return a reference? // (Answer: ?) std::ostream &operator<<(std::ostream &out, const complex::Complex &a) { out << "(" << a.real() << " + " << a.imag() << "i)"; return out; }

Complex5.h D. We must use a reference 5/2/2018 Complex5.h D. We must use a reference A reference to out, the ostream object provided as an reference argument The return value is only there for chaining (but required for chaining to work correctly) Copying of streams is disallowed (and doesn’t make sense)