#include #include using namespace std; /* * Returns a pointer to heap-allocated memory * Note: the syntax is not the best */ vector* object_pointers(){ vector *v = new vector; for( int i = 0; i < 10; i++ ){ (*v).push_back(i); } return v; } /* * Returns a pointer to heap-allocated memory * This is the best syntax: uses the -> operator */ vector* object_pointers_best_approach(){ vector *v = new vector; for( int i = 0; i < 10; i++ ){ v->push_back(i); } return v; } /* * The heap allocated memory is both allocated and * deleted inside the function */ void object_pointers2(){ vector *v = new vector; for( int i = 0; i < 10; i++ ){ v->push_back(i); } for( int i = 0; i < v->size(); i++ ){ cout << v->at(i) << endl; } // Since we do not return a pointer to the heap // allocated memory back to the caller, we must // call delete or we have a memory leak! delete v; } /* * A pointer to stack-allocated memory does not need * to be deleted */ void object_pointers3(){ // pointer to vector, initially points to random location vector* vPtr; // declare and initialize default vector object vector vec; vPtr = &vec; vPtr->push_back(10); vPtr->push_back(20); for( int i = 0; i < vec.size(); i++ ){ cout << i << ": " << vec[i] << endl; } // NOTE: No need to call delete since pointer points to // stack allocated memory not heap allocated memory } void references() { int x = 5; // A reference is declared using the '&' symbol // Notice the rhs is just 'x' int &x_ref = x; // x_ref is now an alias for x cout << "Initial value of x: " << x << endl; cout << "Initial value of x (ref): " << x_ref << endl << endl; x_ref = 10; // No dereferencing symbol needed! cout << "Changed x using reference!" << endl << endl; cout << "New value of x: " << x << endl; cout << "New value of x (ref): " << x_ref << endl; } void address(){ int x = 10; int *x_ptr = &x; cout << "==== Calling method address ====" << endl; cout << "Address: " << x_ptr << endl; cout << "Value: " << *x_ptr << endl; cout << endl; } void changing_values(){ int x = 10; int* x_ptr = &x; cout << "==== Calling method changing_values ====" << endl; cout << "Address: " << x_ptr << endl; cout << "Initial value: " << *x_ptr << endl; *x_ptr = -100; // x = -100; cout << "New value: " << *x_ptr << endl; cout << endl; } void precedence(){ int x = 10; int* x_ptr = &x; cout << "==== Calling method precedence ====" << endl; cout << endl << "Address of ptr: " << x_ptr << endl; cout << "Dereferencing ptr: " << *x_ptr << endl << endl; *x_ptr++; // the * operator has lower precedence cout << "Incremented pointer!" << endl << endl; cout << "Address of ptr: " << x_ptr << endl; cout << "Dereferencing ptr: " << *x_ptr << endl << endl; } void twoPointers(){ int x = 10; int* xPtr = &x; int* xPtr2; xPtr2 = xPtr; (*xPtr2) = 20; cout << "x: " << x << endl; cout << "xPtr: " << xPtr << endl; cout << "xPtr2: " << xPtr2 << endl; } int main(){ /* ===== Functions illustrating simple operations on pointers ===== */ // address(); // changing_values(); // precedence(); /* ===== Example of pointers to heap-allocated memory ===== */ vector* vec_ptr = object_pointers(); // Print the elements of the vector for( int i = 0; i < vec_ptr->size(); i++ ){ cout << vec_ptr->at(i) << endl; } cout << endl; delete vec_ptr; /* ===== Functions illustrating use of references ===== */ references(); return 0; }