Other C++ Features True reference parameters Readings: 3.3,3.5-3.7 Default arguments Readings:...

Preview:

Citation preview

Other C++ Features

• True reference parametersReadings: 3.3,3.5-3.7

• Default argumentsReadings: 4.1-4.7

• C++ Dynamic MemoryReadings 5.1-5.8

Outline

• True reference parametershow to define, how to call, how to use

• Default argumentshow to define, how to call, order effects, legal values

• C++ Dynamic Memorynew, delete keywords

allocating/deleting single instance

allocating/deleting 1D array

allocating/deleting 2D array

True Reference Parameters

C++ has another way of passing parameters -- true reference parametersA true reference parameter gives you a way to change a

variable that is not part of a function without passing it as a pointer

In a function definition you indicate a function parameter by putting an & after the type (no *)Type& Pname

In a call to the function you give the name of the variable

The parameter becomes another way to refer to the variable

A Simple True Reference Parameter

void updateInt(int& num) {

// num becomes a synonym for the var

// used in the function call

num = num + 1;

}

int X = 5;

updateInt(X); // num becomes name for X

cout << X << endl; // Prints 6\n

Reference to a Pointer

• Reference parameters useful for changing pointer vars (so you don’t have to pass a pointer to a pointer)

• Put & after * with type

• Example:

void InitList(LLStruct*& start) {

start = 0;

}

LLStruct *ListStart;

InitList(ListStart);

Reference to a Structure

• Can also pass a reference to a structure:struct TIME { // more on this later

int hours, minutes, seconds;

};

void springForward(TIME& thetime) {

thetime.hours += 1;

}

TIME currtime = {0, 0, 0};

springForward(currtime);

Default Parameter Values

• In C++ you can supply default values for parameters– when calling such functions you can leave out

arguments for some of these parameters

– the default values of those parameters are used in place of arguments

– the function therefore can be called with a different number of arguments

Specifying Default Values

• Format of parameter: Type Pname = DefaultVal– DefaultVal can be any appropriate expression (not

necessarily a constant)

• Rules for including– may have more than one default parameter– default parameters must be the last parameters for function– the order of the default parameters matters

• can leave out last default parameter, last two, last three, etc., but can not pick and choose (can’t leave out last and third to last)

Default Example

void deffunc(int a, float b = 2.0, int c = 3, char d = ‘A’) {

cout << a << ‘ ‘ << b << ‘ ‘ << c << ‘ ‘ << d << endl;

}

calls:deffunc(1); // Outputs 1 2.0 3 A\n

deffunc(1,4.0); // Outputs 1 4.0 3 A\n

deffunc(1,5.0,6); // Outputs 1 5.0 6 A\n

deffunc(1,7.0,8,’B’); // Outputs 1 7.0 8 B\n

Can Use Objects as Defaults

• Objects must be available (generally global)• Example:

void Read_To_Newline(istream& ins = cin) {

while (ins.get() != ‘\n’);

}

– when called, cin is used as parameter ins unless an argument is supplied

Read_To_Newline(); // Reads from keyboard (cin)

Read_To_Newline(myin); // Reads from file myin connected to

Using Expressions as Defaults

• Can use a complex expression as a default value– as long as the expression is well-defined (i.e., generally

involves global variables/functions)

int default_array_length = 20;

char *allocate_array(unsigned int size = ((default_array_length * sizeof(char)) + 1)) {

}

Dynamic Memory Allocation

• Space on the heap is allocated using the keyword new to create a new instance (similar to malloc)

• The space can be returned to the heap using the keyword delete (similar to free)

• There are no routines corresponding to calloc and realloc (though it is easy enough to write your own version of calloc)

Allocating a Single Element

• Use new Type to create element of type Type• Examples:

int* iptr = new int;float* fptr = new float;char* cptr = new char;int** iptrptr = new int*;– each of these variables points to a new element of the

appropriate type (a lot easier than malloc, eh?)– can also use new during code:int* iptr2;iptr2 = new int; // As opposed to// iptr2 = (int *) malloc(sizeof(int));

Initializing the Resulting Space

• Using the basic format (new Type), the resulting space is not initialized

• If you add an empty pair of parentheses (), the space is initialized to 0

• If you add a pair of parentheses with an appropriate value in between (val), the space is initialized to val

• Examplesint i1ptr = new int; // new space, ? val

int i2ptr = new int(); // new space, 0 val

int i3ptr = new int(42); // new space, 42 val

Deleting an Instance

• Use delete keyword followed by pointer to space allocated on heap:delete pointer;

• Examples:int* iptr = new int;

float *fptr = new float;

int** iptrptr = new int*;

delete iptr; // free space iptr connected to

delete fptr;

delete iptrptr;

Allocating a 1-Dimensional Array

• Use square brackets, size after type in new:new Type[rows]

• Variable should be a pointer to type Type• Example:

int size = 10;

int* iarray = new int[size];

float* farray = new float[size*2];

int** iptrarray = new int*[size+1];– error to put parentheses around type

Releasing 1D Array

• To release 1-dimensional array use delete, but put [] between keyword delete and pointer:delete [] aptr;

• The brackets inform C++ you are giving back a group of memory

• Example:int* iarray = new int[10];

delete [] iarray;

Allocating Space for String

• Use new to allocate space for length of string plus one extra for delimiter

• Example:char *basestr = “hello”;

char *copystr;

copystr = new char[strlen(basestr)+1];

strcpy(copystr,basestr);

Allocating 2-Dimensional Array

• Use technique similar to what we did in C:Type** twodname;

twodname = new Type*[dimension1];

for (int d1 = 0; d1 < dimension1; d1++)

twodname[d1] = new Type[dimension2];

• Releasing array:for (int d1 = 0; d1 < dimension1; d1++)

delete [] twodname[d1];

delete [] twodname;

2D Array Example int **A;

A = new int*[5]; for (int i = 0; i < 5; i++) { A[i] = new int[8]; for (int j = 0; j < 8; j++) A[i][j] = i + j; }

for (int i = 0; i < 5; i++) { for (int j = 0; j < 8; j++) cout << setw(3) << A[i][j]; cout << endl; }

for (int i = 0; i < 5; i++) delete [] A[i]; delete [] A;

Example: Array of Strings#include <stdlib.h>#include <iostream.h>#include <iomanip.h>#include <fstream.h>#include <string.h>

void main() { const int BUFSIZE = 256; int maxlines = 32; int numlines = 0; ifstream fin; ofstream fout; char buffer[BUFSIZE]; char **lines = new char*[maxlines]; char **savelines;

Example: Array of Strings cout << "File to read: "; cin >> buffer; fin.open(buffer); if (!fin) { cout << "Unable to open " << buffer << endl; exit(0); } while (!((fin.getline(buffer,BUFSIZE)).eof())){ if (numlines == maxlines) { maxlines *= 2; savelines = lines; lines = new char*[maxlines]; for (int i = 0; i < numlines; i++) lines[i] = savelines[i]; delete [] savelines; } lines[numlines] = new char[strlen(buffer)+1]; strcpy(lines[numlines],buffer); numlines++; } fin.close();

Example: Array of Strings cout << "File to save: "; cin >> buffer;

fout.open(buffer);

if (!fout) {

cout << "Unable to open " << buffer << endl;

exit(0);

}

for (int i = 0; i < numlines; i++)

fout << lines[i] << endl;

fout.close();

}

Recommended