Download presentation
Presentation is loading. Please wait.
Published byRandolph Jenkins Modified over 9 years ago
2
C++ Review CS 302 – Data Structures
3
Review Topics Calling functions by value or reference Pointers and reference variables Static and dynamic arrays Constructors, destructors and copy-constructors Operator overloading
4
Functions Section 2.2
5
Two ways to call a function: Call by “value” –Useful for “protecting” the values of the variables passed to a function. Call by “reference” –Useful for "returning” multiple values. Need to define “formal” and “actual” function parameters first …
6
int FindMax(int x, int y) { int maximum; if(x>=y) maximum = x; else maximum = y; return maximum; } “FindMax” Example
7
“FindMax” Example (cont.) #include int FindMax(int, int); // function prototype int main() { int firstnum, secnum, max; cout << "\nEnter two numbers: "; cin >> firstnum >> secnum; max=FindMax( firstnum, secnum); // the function is called here cout << "The maximum is " << max << endl; return 0; }
8
The argument names in the function header are referred to as formal parameters. int FindMax(int x, int y) { int maximum; if(x>=y) maximum = x; else maximum = y; return maximum; } Formal Parameters x, y are called “formal parameters”
9
Actual Parameters The argument names in the function call are referred to as actual parameters #include int FindMax(int, int); // function prototype int main() { int firstnum, secnum, max; cout << "\nEnter two numbers: "; cin >> firstnum >> secnum; max=FindMax( firstnum, secnum); // the function is called here cout << "The maximum is " << max << endl; return 0; } firstnum, secnum are called “actual parameters”
10
Calling a function by “value” The formal parameters receive a copy of the actual parameter values. The function cannot change the values of the actual parameters.
11
#include void newval(float, float); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(firstnum, secnum); cout << firstnum << secnum << endl; return 0; } void newval(float xnum, float ynum) { xnum = 89.5; ynum = 99.5; } Calling a function by value (cont.)
12
Calling a function by “reference” The formal parameters become an alias for the actual parameters. The function can change the values of the actual parameters. Note: formal parameters must be declared as “reference” variables.
13
#include void newval(float&, float&); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(firstnum, secnum); cout << firstnum << secnum << endl; return 0; } void newval(float& xnum, float& ynum) { xnum = 89.5; ynum = 99.5; } Calling a function by reference (cont.) reference variables!
14
The "const" modifier Call by reference is the preferred way to pass a large structure or class instances to functions, since the entire structure need not be copied each time it is used! C++ provides us with protection against accidentally changing the values of variables passed by reference with the const operator int FindMax(const int& x, const int& y);
15
Pointers and Reference Variables
16
Reference variables A reference variable stores the address of another variable. Reference variables must be initialized during declaration. #include void main() { int x = 3; int& y = x; cout << "x= " << x << "y = " << y << endl; y = 7; cout << "x= " << x << "y = " << y << endl; }
17
Reference variables and pointers A reference variable is a constant pointer (after initializing a reference variable, we cannot change it again). Reference variables are dereferenced automatically (no need to use the dereferencing operator *).
18
int b; // using reference variables int& a = b; a = 10; int b; // using pointers int *a = &b; *a = 10; Reference variables and pointers (cont.)
19
#include void newval(float&, float&); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(firstnum, secnum); cout << firstnum << secnum << endl; return 0; } void newval(float& xnum, float& ynum) { xnum = 89.5; ynum = 99.5; } “Call by reference” - revisited no dereferencing !
20
#include void newval(float *, float *); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(&firstnum, &secnum); cout << firstnum << secnum << endl; return 0; } void newval(float *xnum, float *ynum) { *xnum = 89.5; *ynum = 99.5; } Same example, using pointers … dereferencing is required ! pass address explicitly
21
Static / Dynamic Array Allocation Section 2.2
22
Two ways to allocate memory for an array: “Static” array allocation –Could waste memory. –Less efficient when passing a statically allocated array to a function. “Dynamic” array allocation –More memory efficient. –More efficient to pass a dynamically allocated array to a function.
23
Static Arrays When a static array is created, the compiler automatically creates an internal pointer constant (i.e., cannot change its contents). The name of the array becomes the name of the pointer constant. The pointer stores the starting address (base address) of the array (i.e., address of first byte)
24
1D Static Arrays (cont.) assume arr is of type “int” and that “int” takes 2 bytes int arr[6]; Need 12 bytes of contiguous memory!
25
Referring to arr[i] causes the compiler, internally, to make the following address computation: &arr[i] = &arr[0] + (i * sizeof(int)) Example: offset to arr[3] = 3 x 2 = 6 bytes 1D Static Arrays (cont.) base address offset
26
2D Static Arrays Static 2D arrays are always stored in memory as 1D arrays in contiguous memory. e.g,
27
Dynamic Array Allocation Allocate memory at run time using the new operator : –Reserves the number of bytes requested by the declaration. –Returns the address of the first reserved location or NULL if sufficient memory is not available. new arr = new int[N]; must be a pointer
28
Dynamic Array Allocation (cont.) Individual elements can be processed using index notation: –e.g., arr[1]=10; cout << "Enter array size: "; cin >> N; int *arr; new arr = new int[N];
29
Dynamic Array De-allocation To de-allocate any memory that has been previously allocated using new, we need to use the delete operator. –Releases a block of bytes previously reserved. –Needs the address of the first location only. delete delete [ ] arr;
30
Example: 2D arrays Suppose we need to allocate a 2 x 6 array: arr[2][6] 480482484486488490
31
Example: 2D arrays (cont.) cout << "Enter numRows and numCols: "; cin >> numRows >> numCols; int **arr2D; arr2D = new int* [numRows]; // allocation for(i=0; i<numRows; i++) arr2D[i] = new int[numCols]; for(i=0; i<numRows; i++) // deallocation delete [] arr2D[i]; delete [] arr2D; Individual elements can be processed using index notation: –e.g., arr2D[0][2]=10;
32
Static Arrays as Function Arguments To pass the whole array to a function, you need to specify the name of the array. In the case of 2D arrays, the number of columns must be specified in the function prototype and heading.
33
#include float find_average(int [], int); void main() { const numElems = 5; int arr[numElems] = {2, 18, 1, 27, 16}; cout << "The average is " << find_average(arr, numElems) << endl; } float find_average(int vals[], int n) { int i; float avg; avg=0.0; for(i=0; i<n; i++) avg += vals[i]; avg = avg/n; return avg; } Static Arrays: 1D Example
34
#include float find_average(int [][2], int, int); // function prototype void main() { const numRows = 2; const numCols = 2; int arr2D[numRows][numCols] = {2, 18, 1, 27}; cout << "The average is " << find_average(arr2D, numRows, numCols) << endl; } Static Arrays: 2D Example
35
float find_average(int vals[][2], int n, int m) { int i,j; float avg; avg=0.0; for(i=0; i<n; i++) for(j=0; j<m; j++) avg += vals[i][j]; avg = avg/(n*m); return avg; } Static Arrays: 2D Example (cont.)
36
#include float find_average(int *, int); // function proptotype void main() { int *arr, numElems;; cin << numElems; arr = new int[numElems]; // then, initialize array … cout << "The average is " << find_average(arr, numElems) << endl; } Dynamic Arrays: 1D Example
37
float find_average(int *vals, int n) { int i; float avg; avg=0.0; for(i=0; i<n; i++) avg += vals[i]; avg = avg/n; return avg; } Dynamic Arrays: 1D Example (cont.)
38
#include float find_average(int **, int, int); // function prototype void main() { int **arr2D; arr2D = new int*[numRows]; for(i=0; i<numRows; i++) arr2D[i] = new int[numCols]; // then, initialize array … cout << "The average is " << find_average(arr2D, numRows, numCols) << endl; } Dynamic Arrays: 2D Example
39
float find_average(int **vals, int n, int m) { int i, j; float avg; avg=0.0; for(i=0; i<n; i++) for(j=0; j<m; j++) avg += vals[i][j]; avg = avg/(n*m); return avg; } Dynamic Arrays: 2D Example (cont.)
40
Constructors, Destructors and Copy-Constructors Section 2.3, p. 140, pp. 360-367
41
What is a constructor? A member function which initializes a class. A constructor has: (i) the same name as the class itself (ii) with or without arguments, no return type
42
Comments on constructors A constructor is called automatically whenever a new instance of a class is created. If you do not specify a constructor, the compiler generates a default constructor for you (expects no parameters and has an empty body).
43
class rectangle { private: float height; float width; int xpos; int ypos; public: rectangle(float, float); // constructor void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function }; rectangle::rectangle(float h, float w) { height = h; width = w; xpos = 0; ypos = 0; }
44
void main() { rectangle rc(3.0, 2.0); rc.posn(100, 100); rc.draw(); rc.move(50, 50); rc.draw(); } Warning: attempting to initialize a data member of a class explicitly in the class definition is a syntax error.
45
class rectangle { private: float height; float width; int xpos; int ypos; properties pr; // another object public: rectangle(float, float, int, int ); // constructor void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function }; Object Composition A class may have objects of other classes as members.
46
Object Composition (cont.) class properties { private: int color; int line; public: properties(int, int); // constructor }; properties::properties(int c, int l) { color = c; line = l; }
47
Object Composition (cont.) rectangle::rectangle(float h, float w, int c, int l):pr(c, l) { height = h; width = w; xpos = 0; ypos = 0; }; void main() { rectangle rc(3.0, 2.0, 1, 3); ……… }
48
What is a destructor? A member function which deletes an object. A destructor has: (i) the same name as the class but is preceded by a tilde (~) (ii) no arguments and returns no values
49
Comments on destructors A destructor is called automatically whenever an object goes out of scope or when the program terminates. If you do not specify a destructor, the compiler generates a default destructor for you. When a class contains a pointer to memory you allocate, it is your responsibility to release the memory before the class instance is destroyed.
50
class string { private: char *s; int size; public: string(char *); // constructor ~string(); // destructor }; string::string(char *c) // constructor { size = strlen(c); s = new char[size+1]; strcpy(s,c); } string::~string() // destructor { delete []s; }
51
It is a member function which initializes an object using another object of the same class. A copy constructor has the following general function prototype: class_name (const class_name&); What is a copy constructor?
52
class rectangle { private: float height; float width; int xpos; int ypos; public: rectangle(float, float); // constructor rectangle(const rectangle&); // copy constructor void draw(); // draw member function void posn(int, int); // position member function void move(int, int); // move member function };
53
rectangle::rectangle(const rectangle& old_rc) { height = old_rc.height; width = old_rc.width; xpos = old_rc.xpos; ypos = old_rc.ypos; } void main() { rectangle rc1(3.0, 2.0); // use constructor rectangle rc2(rc1); // use copy constructor ………… }
54
Comments on copy constructors In the absence of a copy constructor, the C++ compiler builds a default copy constructor for each class which is doing a member-wise copy between objects. The default copy constructor will not work well if the class contains pointer data members...
55
#include class string { private: char *s; int size; public: string(char *); // constructor ~string(); // destructor void print(); void copy(char *); }; void string::print() { cout << s << endl; } Note: no user defined copy constructor! void string::copy(char *c) { strcpy(s, c); }
56
void main() { string str1("George"); string str2 = str1; // default copy constructor str1.print(); // what is the output ? str2.print(); str2.copy("Mary"); str1.print(); // what is the output now ? str2.print(); }
57
Defining a copy constructor … class string { private: char *s; int size; public: string(char *); // constructor ~string(); // destructor string(const string&); // copy constructor void print(); void copy(char *); };
58
string::string(const string& old_str) { size = old_str.size; s = new char[size+1]; strcpy(s,old_str.s); } void main() { string str1("George"); string str2 = str1; str1.print(); // what is printed ? str2.print(); str2.copy("Mary"); str1.print(); // what is printed now ? str2.print(); }
59
Operator Overloading pp. 367-370
60
What is operator overloading? Changing the definition of an operator. Need to write a function for the operator we are overloading.
61
Special cases The address operator (&) may be used with objects of any class without explicit overloading. –It returns the address of the object in memory. The assignment operator (=) may be used with every class without explicit overloading, however, its default behavior is a member-wise assignment of the data members of the class.
62
Example: overloading the assignment operator The default overloading is not enough for classes with pointer members. void operator=(class_name&); class string { private: char *s; int size; public: string(char *); // constructor ~string(); // destructor void operator=(string&); void print(); void copy(char *); };
63
void string::operator=(string& old_str) { delete [] s; // must release previously assigned memory size = old_str.size; s = new char[size+1]; // assign new memory strcpy(s, old_str.s); } void main() { string str1("George"); string str2("Mary"); string str3("John"); str1.print(); // what is printed ? str2.print(); str3.print(); str3 = str1; str2 = str1; str1.copy(“Kate"); str1.print(); // what is printed now ? str2.print(); str3.print(); }
64
Handling multiple assignments (e.g., x=y=z;) string& string::operator=(const string& old_str) { if (this != &old_str) { // make sure not same object delete [] s; // delete old name's memory size = old_str.size; s = new char[size+1]; // allocate new memory strcpy(s, old_str.s); // copy new string } return *this; // return ref for multiple assignment } //end operator=
65
What is the main difference between the copy constructor and the assignment operator? The copy constructor creates a new object. The assignment operator works on an already valid object.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.