Module 2 Parameters Overloading Methods and Random Garbage
Module 2 Parameters, Overloading Methods, and Random Garbage CSE 1322 4/26/2018 11 -1
Overview See different ways to pass parameters • By reference • By value • By 'out' • See how 'garbage' is created • Demonstrate the ref keyword in C# 10/23/2021 2
Review: What is a Method? Think of a method as a black box that contains the detailed implementation for a specific task. The method may use inputs (parameters) and may return an output with a specific type. 10/23/2021 3
Method Structure Modifiers Method Header Method Body 10/23/2021 Return Type Method Name Formal Parameters public static int add. Two. Nums (int x, int y) { return x + y; } 4
Calling the Method Modifiers Method Header Method Body Return Type Method Name Formal Parameters public static int add. Two. Nums (int x, int y) { return x + y; } Actual parameters (called ”arguments”) int result = add. Two. Nums (5, 2); 10/23/2021 5
Parameters There are three main types of parameters: 1. Value - passes a copy of the value of the variable to the method. This is the default. 2. Reference (C#)- passes a reference to the actual variable. Keyword is ref. Use this when you want to pass a value in and have any change to that value be persistent when the method is complete 3. Out (C#) - passes a reference to the actual variable. Keyword is out. Use this when you want the method to initialize a value and place it for later use in the actual variable (persists when the method is complete) 4. Note that Java passes all parameters by value. 5. C++ uses both Call-by-reference and Call-by-value 4/26/2018 11 -6
Example 1 - and the output is ? static void B (int x) { // Built-in type argument passing x += 9; PRINT (x); } public static void M/main (S/string[] args) { int a = 42; PRINT (a); // Prints 42 B (a); // Prints 51 because is call-by-value; PRINT (a); // Prints 42 } 4/26/2018 11 -7
Example 2 - and the output is ? static void B (ref int x) { x += 9; Console. Write. Line (x); } public static void Main (string[] args) { int a = 42; Console. Write. Line (a); // Prints 42 B (ref a); // Prints 51 BUT! a has changed! Console. Write. Line (a); // Prints 51 } 4/26/2018 11 -8
What about out? • Remember, this is used to initialize a variable • Why even have it? We have ref, right? • Honestly, out isn’t used often, but: • Marks the “intent” of what you’re doing • Could prevent bad data from coming in 4/26/2018 11 -9
Example 3 - and the output is ? static void B (out int x) { x = 9; Console. Write. Line (x); } public static void Main (string[] args) { int a; // We can't print this yet - not initialized B (out a); // Initializes a and prints 9 Console. Write. Line (a); // Prints 9 } 4/26/2018 11 -10
What about Complex Data Types? • With classes/objects, we still pass by value • HOWEVER, we are copying the reference • We’ll start with code, then look at what’s going on 4/26/2018 11 -11
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; PRINT(x. weight); } public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 0; PRINT(my. Dog. weight); } 4/26/2018 11 -12
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; PRINT(x. weight); } public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 10; PRINT(my. Dog. weight); } 4/26/2018 11 -13
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; PRINT(x. weight); } public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 10; PRINT(my. Dog. weight); } // PRINTS 10 to the screen 4/26/2018 11 -14
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; PRINT(x. weight); } x public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 10; PRINT(my. Dog. weight); } // MAGIC HAPPENS! x is a copy of my. Dog. . . // That is, x points to the same thing // my. Dog points to 4/26/2018 11 -15
IMPORTANT Watch what happens to the weight variable 4/26/2018 11 -16
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; // Look at weight before… PRINT(x. weight); } x public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 10; PRINT(my. Dog. weight); } 4/26/2018 11 -17
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; // Look at weight after! PRINT(x. weight); } x public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 19; PRINT(my. Dog. weight); } 4/26/2018 11 -18
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; PRINT(x. weight); // print out 19 } x public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 19; PRINT(my. Dog. weight); } 4/26/2018 11 -19
class Dog { public int weight; } static void B(Dog x) { x. weight += 9; PRINT(x. weight); } x public static void M/main(S/string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; PRINT(my. Dog. weight); B(my. Dog); weight = 19; PRINT(my. Dog. weight); // print out 19 } 4/26/2018 11 -20
IMPORTANT Now, my. Dog’s weight has now changed! 4/26/2018 11 -21
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } 4/26/2018 11 -22
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; weight = 0; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } 4/26/2018 11 -23
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } 4/26/2018 11 -24
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } // OUTPUT 10 4/26/2018 11 -25
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog == x public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } 4/26/2018 11 -26
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { weight = 0; x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog == x public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } // Uh oh. . . 4/26/2018 11 -27
Our first piece of garbage • No one is pointing to the old dog anymore! • We’ve created trash • Yes, it’s really called that (or garbage) • Yes, we have a garbage collector (GC) • The GC picks up unloved objects • There’s no way to recover the unloved dog • Rule: when no one points to an object, it’s TRASHED! 4/26/2018 weight = 0; my. Dog == x weight = 10; 11 -28
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { weight = 9; x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog == x public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } 4/26/2018 11 -29
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { weight = 9; x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog == x public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } // OUTPUT 9 to the screen 4/26/2018 11 -30
What about adding ref? class Dog { public int weight; } static void B(ref Dog x) { weight = 9; x = new Dog(); x. weight = 9; Console. Write. Line(x. weight); } my. Dog == x public static void Main(string[] args) { Dog my. Dog = new Dog(); my. Dog. weight = 10; Console. Write. Line(my. Dog. weight); B(ref my. Dog); Console. Write. Line(my. Dog. weight); } // OUTPUT 9 to the screen AGAIN because my. Dog has changed 4/26/2018 11 -31
A little more detail • Did we just see “pointers” from C/C++? • Yes and no - Concepts are the same • What you saw was working with memory addresses • They’re called “references” because they refer to another chunk of memory • What about changing primitive data types? • C# has the ref keyword • Allows changes to be made • Java students: you still need to know this! 10/23/2021 32
Note to Java Folks • You still need to do this from time to time • There’s no ref keyword in java, so you can: • Make the variable a global variable (or a public variable in the class) • Have the function return a value and assign that to the variable in the calling function: int change_x (int x) { x++; return (x); } 10/23/2021 CSE 1321 Module 4 33
Pass-by-value vs. Pass-by-reference vs. Passby-reference-type • Be careful to note the difference between a pass-by-reference parameter and a parameter of a reference type. • Use the activation stack to track local variables and how parameters of the above types affect the variables from one stack frame to the next. 4/26/2018 11 -34
Overloading Methods • Method overloading: using the same method name for multiple methods • Do not confuse with overriding (from inheritance) • The signature of each overloaded method must be unique • The signature includes the number, type, and order of the parameters • The compiler determines which version of the method is being invoked by analyzing the parameters • The return type of the method is not part of the signature 4/26/2018 11 -35
Overloading Methods float try. Me (int x) { return x +. 375; } float try. Me (int x, float y) { return x*y; } // Which try. Me is called? result = try. Me (25, 4. 32 f); 4/26/2018 11 -36
Overloading Operators • In C# and C++, not only can methods be overloaded, even operators (e. g. +, -, *, /, ==, ++, etc) can be overloaded. • Java does not allow operator overloading 4/26/2018 11 -37
Operator overloading • C# enables you to overload most operators to make them sensitive to the context in which they are used. • Use operator overloading when it makes an application clearer than accomplishing the same operations with explicit method calls. • Example: Class Complex. Number overloads the plus (+), minus (-) and multiplication (*) operators to enable programs to add, subtract and multiply instances of class Complex. Number using common mathematical notation 4/26/2018 11 -38
Rules for Operator Overloading • Keyword operator, followed by an operator symbol, indicates that a method overloads the specified operator. • Methods that overload binary operators must take two arguments —the first argument is the left operand, and the second argument is the right operand. • Overloaded operator methods must be public and static. 4/26/2018 11 -39
public class Dog { public string name; public int weight; public Dog(string name, int weight) { this. name = name; this. weight = weight; } public static Dog operator+ (Dog d 1, Dog d 2) {// Overload the + operator Dog merged. Dog = new Dog("Combo. Dog", 0); merged. Dog. name = d 1. name+": "+d 2. name; merged. Dog. weight = d 1. weight+d 2. weight; return merged. Dog; } } class Main. Class { public static void Main(String[] args) { Dog my. Dog = new Dog("CSE", 8); Dog your. Dog = new Dog ("1322", 9); Dog uber. Dog = my. Dog + your. Dog; // Add two dogs together! Console. Write. Line (uber. Dog. name + " weighs " + uber. Dog. weight); } } // OUTPUT is CSE: 1322 weighs 17 4/26/2018 11 -40
- Slides: 40