Starting Out with C++: Early Objects
5
thEdition
Topics
Getting the Address of a Variable Pointer Variables
The Relationship Between Arrays and Pointers
Topics
(continued)
Comparing Pointers
Pointers as Function Parameters Dynamic Memory Allocation
Returning Pointers from Functions
Pointers to Structures and Class Objects
11 When to Use ., When to Use ->, and
10.1 Getting the Address of a
Variable
• Each variable in program is stored at a unique address
• Use address operator & to get address of a variable:
int num = -23;
10.2 Pointer Variables
• Pointer variable (pointer): variable that holds an address
• Can perform some tasks more easily with an address than by accessing memory via a symbolic name:
– Accessing unnamed memory locations – Array manipulation
Pointer Variables
• Definition:
int *intptr;
• Read as:
“intptr can hold the address of an int” • Spacing in definition does not matter:
Pointer Variables
• Assignment:
int num = 25; int *intptr;
intptr = #
• Memory layout:
Can access num using intptr and indirection operator *:
cout << intptr; // prints 0x4a00
cout << *intptr; // prints 25
num intptr
25 0x4a00
C++ Spring 2000 Arrays 8
Pointers
A pointer is a variable that holds the
address of
something else. . . . . . . MEMORY 0 1 2 3 4 5 81345 81346 81347 Address int foo; int *x;
foo = 123; x = &foo;
foo
x
123
9
int *x;
• x is a pointer to an integer.
• You can use the integer x points to in a C++ expression like this:
y = *x + 17;
*x = *x +1;
&foo
In C++ you can get the address of a
variable with the “&” operator.
. . . . . . MEMORY 0 1 2 3 4 5 Address
&foo means “the address of foo”
foo
int foo;
foo = 123;
11
Assigning a value to a
dereferenced
pointer
A pointer must have a value before you can dereference it (follow the pointer).
int *x;
*x=3; int foo;int *x;
x = &foo; *x=3;
ERROR!!! x doesn’t p
oint to anyth
ing!!!
this is fine x points to f
12
Pointers to anything
int *x; int **y;
double *z;
x some int
some *int some int
y
10.3 The Relationship
Between Arrays and Pointers
• Array name is starting address of array
int vals[] = {4, 7, 11};
cout << vals; // displays 0x4a00 cout << vals[0]; // displays 4
4 7 11
The Relationship Between
Arrays and Pointers
• Array name can be used as a pointer constant
int vals[] = {4, 7, 11};
cout << *vals; // displays 4
• Pointer can be used as an array name
int *valptr = vals;
Pointers in Expressions
Given:
int vals[]={4,7,11}; int *valptr = vals;
What is valptr + 1?
It means (address in valptr) + (1 * size of an int)
cout << *(valptr+1); // displays 7 cout << *(valptr+2); // displays 11
Array Access
Array elements can be accessed in many ways
Array access method
Example
array name and [ ] vals[2] = 17; pointer to array and [ ] valptr[2] = 17;
array name and
subscript arithmetic *(vals+2) = 17; pointer to array and
Array Access
• Array notation
vals[i]
is equivalent to the pointer notation
*(vals + i)
10.4 Pointer Arithmetic
• Some arithmetic operators can be used with pointers:
- Increment and decrement operators ++,
-19
Pointer arithmetic
• Integer math operations can be used with pointers.
• If you increment a pointer, it will be increased by the size of whatever it points to.
int a[5];
a[0] a[1] a[2] a[3] a[4] int *ptr = a;
*ptr
*(ptr+2)
Pointer Arithmetic
• Assume the variable definitions
int vals[]={4,7,11}; int *valptr = vals;
• Examples of use of ++ and
valptr++; // points at 7
Pointer Arithmetic
• Assume the variable definitions:
int vals[]={4,7,11}; int *valptr = vals;
• Example of use of + to add an int to a
pointer:
cout << *(valptr + 2)
Pointer Arithmetic
• Assume the variable definitions:
int vals[]={4,7,11}; int *valptr = vals;
• Example of use of +=:
Pointer Arithmetic
• Assume the variable definitions
int vals[] = {4,7,11}; int *valptr = vals;
• Example of pointer subtraction
valptr += 2;
cout << valptr - val;
This statement prints 2: the number of
10.5 Initializing Pointers
• Can initialize to NULL
int *ptr = NULL;
• Can initialize to addresses of other variables
int num, *numPtr = #
int val[ISIZE], *valptr = val;
• Initial value must have correct type
float cost;
10.6 Comparing Pointers
• Relational operators can be used to compare addresses in pointers
• Comparing addresses in pointers is not the same as comparing contents pointed at by pointers:
if (ptr1 == ptr2) // compares // addresses if (*ptr1 == *ptr2) // compares
10.7 Pointers as Function
Parameters
• A pointer can be a parameter
• Works like a reference parameter to allow change to argument from within function • A pointer parameter must be explicitly
Pointers as Function Parameters
• Requires:
1) asterisk * on parameter in prototype and
heading
void getNum(int *ptr);
2) asterisk * in body to dereference the pointer
cin >> *ptr;
3) address as argument to the function
Pointers as Function
Parameters
void swap(int *x, int *y) {
int temp;
temp = *x; *x = *y; *y = temp; }
10.8 Dynamic Memory
Allocation
• Can allocate storage for a variable while program is running
• Uses new operator to allocate memory
double *dptr;
dptr = new double;
Dynamic Memory Allocation
• Can also use new to allocate array
arrayPtr = new double[25];
– Program terminates if there is not sufficient memory
• Can then use [ ] or pointer arithmetic to
Releasing Dynamic Memory
• Use delete to free dynamic memory
delete dptr;
• Use delete [] to free dynamic array
memory
delete [] arrayptr;
10.9 Returning Pointers from
Functions
• Pointer can be return type of function
int* newNum();
• Function must not return a pointer to a local variable in the function
• Function should only return a pointer
– to data that was passed to the function as an argument
10.10 Pointers to Structures and
Class Objects
• Can create pointers to objects and structure variables
Student stu1;
Student *stuPtr = &stu1; Square sq1[4];
Square *squarePtr = &sq1[0];
• Need () when using * and .
Structure Pointer Operator
• Simpler notation than (*ptr).member
• Use the form ptr->member:
stuPtr->studentID = 12204; squarePtr->setSide(14);
in place of the form (*ptr).member:
Dynamic Memory with Objects
• Can allocate dynamic structure
variables and objects using pointers:
stuPtr = new Student;
• Can pass values to constructor:
squarePtr = new Square(17);
• delete causes destructor to be invoked:
36
C++ strings
• A string is a null terminated array of characters.
– null terminated means there is a character at the end of the the array that has the
value 0 (null).
• Pointers are often used with strings:
char *msg = “RPI”; 'R'
msg zero (n
ull)
37
String Manipulation Functions
• C++ includes a library of string handling functions:
char * strcpy(char *dst, const char *src)
char * strcat(char *dst, const char *src)
38
String Example - Count the
chars
int count_string( char *s) { int n=0;
while (*s) { n++;
s++; }
return(n); }
while the thing po
inted
to by s is not null
increment count
39
Another way
int count_string( char *s) { char *ptr = s;
while (*ptr) { ptr++;
}
return(ptr - s); }
Pointers
int *intPtr;
intPtr = new int;
*intPtr = 6837;
delete intPtr;
int otherVal = 5;
intPtr = &otherVal;
Create a pointer
Allocate memory
Set value at given address
Change intPtr to point to
a new location
Function return type array
#include <iostream> int* someFunction() {
int* array = new int[10];
array[0]=10;
array[1]=54;
return array; }
int main() {
int* array = someFunction();
cout << array[0] << " " << array[1]; delete[] array;
Function return type pointer & refrence
#include <iostream>
double & GetWeeklyHours() {
double h = 46.50; double &hours = h; return hours;
}
double * GetSalary() {
double salary = 26.48;
double *HourlySalary = &salary; return HourlySalary;
}
double * GetSalary() {
Function return type pointer & refrence
#include <iostream>
double & GetWeeklyHours() {
double h = 46.50; double &hours = h; return hours;
}
double * GetSalary() {
double salary = 26.48;
double *HourlySalary = &salary; return HourlySalary;
}
int main() {
double hours = GetWeeklyHours(); double salary = *GetSalary();
cout << "Weekly Hours: " << hours << endl; cout << "Hourly Salary: " << salary << endl; double WeeklySalary = hours * salary;
cout << "Weekly Salary: " << WeeklySalary << endl; return 0;
Pointer to object member -
:: *
• Whenever object is created memory is allocated. The data defining the object is held in the space allocated to it.
• The data and member function of the object reside at a specific memory location,Thus a pointer to an object member can be obtained by applying the address of operator (&).
• Member of class can accessed using either pointer to object or pointer to member itself.
• A pointer o class members is declared using the operator :: *
member name of a class similar to variables. • Syntax for defining the pointer to class
• Data _type class_name :: * pointername
Pointer to object member -
:: *
• Pointer name = & class_name::member;
• A variable of type pointer to a member of class X can be defined as follows:
• Datatype X:: *ptr_name
• prt _name is a datamember of class X which is of type datatype.
• As pointer to a member function can be defined as follows:
• Return type(X::* fn_ptr)(arguments);
Access through object
.*
• C++ provides operator .* (dot-star)
exclusively for use with pointers to
members called member dereference
operator.
Access through object
->*
• C++ also provide another operator (->*)
exclusively for use with pointers to
members called member dereference
operator.
Example
• Class_name obj1; • Class_name *obj2;
• Create the object obj1 of the class • Using the pointer variable you can
access data member such as:
• Obj1.*ip=20; if ip is bound to a it is same as the obj1.a
Example
::* , .*, ->*
• #include<iostream.h> • class name
• { int y; public: int a,b; int init(int z)
{ a=z; return z; } • };
• main() {
• int name::*ip; //pointer to member
• ip=&name::a; //address of a can be assigned
• // or int name :: *ip=&name :: a • name n1; n1.*ip=10;
• cout<<n1.*ip<< n1.a; • name *obj1;
Example
::* , .*, ->*
• cout<<obj1->*ip<<n1.a; • name *pr=&n1;
• name *ptr1=new name; • (*pr).a=7;
• int (name :: *ptr_init(int);// pointer to member function • ptr_init =&name::init;// pointer to member funvtion init() • // access through object
• (n1.*ptr_init)(5);
• Cout<<“a in obj , after n1.*prtinit(5)=” <<n1.a<<endl; • // access through object pointer
• (obj1->*ptr_init)(5); • Cout<<n1.a<< endl;
Ambiguity
• We know that compiler will decide which function to be invoked among the overloaded functions. When the compiler could not choose a function between two or more overloaded functions, the situation is called as an ambiguity in function overloading.
• When the program contains ambiguity, the compiler will not compile the program.
• The main cause of ambiguity in the program · Type conversion
Friend class
• A class can also be declared to be the friend of some other class. When we create a friend class then all the
member functions of the friend class also become the friend of the other
Friend class properties
• Friend functions have the following properties:
• 1) Friend of the class can be member of some other class.
• 2) Friend of one class can be friend of another class or all the classes in one program, such a friend is known as GLOBAL FRIEND.
• 3) Friend can access the private or protected members of the class in which they are declared to be friend, but they can use the members for a specific object.
• 4) Friends are non-members hence do not get “this” pointer.
• 5) Friends, can be friend of more than one class, hence they can be used for message passing between the classes.
Program using friend class
• #include<iostream.h> • class Storage
• { private: int m_nValue; double m_dValue;
• public:
• Storage(int nValue, double dValue) • { m_nValue = nValue;
• m_dValue = dValue; • }
• // Make the Display class a friend of Storage
• friend class Display;
Cont…
class Display
{ private: bool m_bDisplayIntFirst; public:
Display(bool bDisplayIntFirst) {
m_bDisplayIntFirst = bDisplayIntFirst; }
void DisplayItem(Storage &cStorage) {
if (m_bDisplayIntFirst)
cout << cStorage.m_nValue << "" << cStorage.m_dValue<<endl; else // display double first
Cont….
• int main()
• { Storage cStorage(5, 6.7); • Display cDisplay(false);