//p is a pointer to a memory location of type integer
//*p will contain actual data
int *p
* ALT: int* p
//p is a pointer to a memory location of type integer
//q is a regular variable
int *p, q
//p & q are pointers to a memory location of type integer
int *p, *q
DEFINITIONS
POINTERS
variables whose content is a memory address/location
C++ doesn't automatically initializes pointer variables
use the following to initializes pointer variables
p = 0 //initialize the variable p to nothing
p = NULL //initialize the variable p to nothing - equivalent to p = 0
ADDRESS OF OPERATOR (&)
the "&" is a unary operator that returns the "address of" its operand
#include <iostream>
using namespace std;
int main()
{
int x = 25;
//p is a pointer to a memory location of type integer
//*p will contain actual data
int *p;
p = &x; //assign the memory address of x to the pointer p
//p = memory address while *p = 25
cout << *p << endl; //print the value pointed by p which is 25
*p = 55; //change the content of memory location pointed by p to 55
//p = memory address of x while *p = 55
//x is now 55
cout << *p << endl; //print the value 55 while "p" is just a memory location
return 0;
}
ASSIGNING MEMORY LOCATIONS
CAVEAT: the two instructions below are different! you can't use the & operator using two pointers
//two pointers - assigning memory location
int *p, *q;
p = q; //this is how you assign the address of q to p with two pointers
//one pointer - assigning memory location
int *p, q;
p = &q;
/********************************************************************************
the declaration int *p, *q declares two pointers, p and q, which can hold the memory address of an integer variable.
however, the assignment of p = &q is not valid because q is not an integer variable - q is a pointer to an integer variable.
therefore, you can't take its address with the "address of" operator (&)
if you want to make p point to q, you can simply assign the value of q to p using the assignment operator (=).
* e.g.,
int *p, *q
p = q;
*********************************************************************************/
OPERATIONS ON POINTER VARIABLES
int main()
{
int *p, *q; //p & q are pointers to a memory location of type integer
char *ch; //ch is a pointer variable to a memory location of type character
double *d; //d is a pointer to a memory location of type double
p = q; //assign the address of q to p
//*p & *q contains data while p & q contains memory address
//any changes made to *p automatically changes the value of
//*q & vice versa
if (p == q) //compare whether p & q points to the same memory location
if (p != q)
p++; //increment p by 4 bytes - p is type integer; p now points +4 bytes from the base memory location
d++; //increment d by 8 bytes - d is type double; d now points +8 bytes from the base memory location
ch++; //increment ch by 1 byte - ch is type char; ch now points +1 byte from the base memory location
return 0;
}
DYNAMIC VARIABLES
these are variables that are created during a program's execution
can be created with the help of pointers
uses the operators "new" and "delete"
the "new" operator is used to create dynamic variables
it allocates memory of the desired type & returns a pointer (the address) to it
the "delete" operator is used to delete dynamic variables
new dataType; //create & allocate a single dynamic variable
new dataType[intExp]; //create & allocate an array of dynamic variables
STATIC VARIABLES
these are variables that are created prior to a program's execution (think pre-loaded)
DYNAMIC ARRAYS
created during program execution
STATIC ARRAYS
fixed size; everytime a program executes, the size of the array is fixed (limitation of static array)
FUNCTIONS & POINTERS
pass-by-value
pass-by-reference
void functionVar(int* &p, double* q){
//both p & q are pointers
//the parameter p is a reference parameter - pass-by-reference
//the parameter q is a value parameter - pass-by-value
}
//this is a fnction with a pointer as a return type
int* functionVar(int* &p, double* q){
//the return type of the function is a pointer of type int
}
ISSUES WITH CLASSES & POINTERS
if one gets deleted, then all are deleted
to resolve this issue, overload the assignment operator IOT have two copies
class List
{
//private: access specifier is assumed by default if not specifically written
int *p, n;
public:
List();
void insertEnd(int);
void print() const;
void destroyList();
};
List::List(){
n = 0;
p = new int[5];
}
int main()
{
List list1, list2
for (int i = 0; i < 5; i++)
list1.insertEnd(10*i);
list2 = list1; //list1 & list2 are both pointed by the same pointer
list1.print(); //0 10 20 30 40
list2.print(); //0 10 20 30 40
list2.destroyList(); //both list1 & list2 will be destroyed
}
const List& List::operator =(const List& otherList){
if (this != &otherList){ //this avoids self-assignment
//the "this" keyword refers to the 1st object
//it refers to the 1st List object NOT the
//otherList object
if (p != NULL)
destroyList();
n = otherList.n;
p = new int[5];
for (int i = 0; i < 5; i++)
p[i] = otherList.p[i];
}
return *this;
}
DYNAMIC VARIABLES IMPLEMENTATION
int main()
{
int *p, x; //p is a pointer to a memory location while *p contains data
p = &x; //assign the memory address of x to p; *p contains data
p = new int; //create a dynamic variable & allocate memory space of type int
char *name; //name is a pointer to a memory location of type char
name = new char[5]; //create an array of dynamic variables
//allocate memory for an array of 5 char elements & store
//the base address of the array in name
strcpy(name, "John"); //store "John" in name
delete[] name; //destroy the memory space allocated for the array name
return 0;
}
OBJECT POINTERS IMPLEMENTATION
class classExample{
int x;
public:
void setX(int a){
x = a;
}
void print(){
cout << "x = " << x << endl;
}
};
int main()
{
classExample *cExpPtr, cExpObject; //cExpPtr is a pointer to a memory location of type classExample
cExpPtr = &cExpObject; //assign the address of cExpObject to cExpPtr;
//*cExpPtr holds actual value
cExpPtr->setX(5); //this syntax is the simply calling the setX function and
//passing the value 5 as argument
//the role of cExpPtr in cExpPtr->setX(5)
//the cExpPtr pointer is used to access the setX() method of the
//cExpObject object - if you remove the pointer, you'll need
//to access the method directly on the object as in
// cExpObject.setX(5) instead of cExpPtr->setX(5)
cExpPtr->print(); //displays x = 5
cExpObject.print(); //displays x = 5
cExpObject.setX(100);
cExpPtr->print(); //displays x = 100
return 0;
}
/***********************************************
NOTE: the bottom portion shows calling the setX & print functions directly via the DOT operator
- the dot operator is used when direct calling (no pointer calling)
NOTE: the top portion shows calling the setX & print functions using a pointer via the arrow operator
- the arrow operator is used when a pointer object calls a function
***********************************************/
OVERLOADING THE ASSIGNMENT OPERATOR IMPLEMENTATION
SOURCE FILE: pointers.cpp
#include <iostream>
using namespace std;
class List
{
int *p, n;
public:
List();
void insertEnd(int);
void print() const;
void destroyList();
const List& operator=(const List& otherList); // overolad the assignment operator
};
List::List(){
n = 0;
p = new int[5];
}
void List::insertEnd(int x){
if(n<5)
p[n++] = x;
}
void List::print() const{
if(n==0)
cout<<"Empty list\n";
else
for (int i = 0; i < n; i++)
cout<<p[i] << " ";
cout << "\n";
}
void List::destroyList(){
delete[] p;
p = NULL;
n = 0;
}
const List& List::operator =(const List& otherList){
if (this != &otherList){ // avoid self-assignment
if (p != NULL)
destroyList();
n = otherList.n;
p = new int[5];
for (int i = 0; i < 5; i++)
p[i] = otherList.p[i];
}
return *this;
}
int main()
{
List l1, l2;
for (int i = 0; i < 5; i++)
l1.insertEnd(10*i);
l2 = l1;
cout << "list1: ";
l1.print();
cout << "list2: ";
l2.print();
l1.destroyList(); //both l1 and l2 will be destroyed!
cout << "list1: ";
l1.print();
cout << "list2: ";
l2.print();
return 0;
}