You are on page 1of 7

Objects and lvalues

An object is a specific region of memory that can hold a fixed or variable value (or set of values). Each value has an associated name and type (also known as a data type). The name is used to access the object and can be a simple identifier or complex expression that uniquely refers the object.

Reference operator (&)


As soon as we declare a variable, the amount of memory needed is assigned for it at a specific location in memory (its memory address). However, in some cases we may be interested in knowing the address where our variable is being stored during runtime in order to operate with relative positions to it.The address that locates a variable within memory is what we call a reference to that variable. This reference to a variable can be obtained by preceding the identifier of a variable with an ampersand sign (&), known as reference operator, and which can be literally translated as "address of". P=&a; This would assign to p the address of variable a, since when preceding the name of the variable a with the reference operator (&). For example: A=25; C=a B=&a; The values contained in each variable after the execution of this, are shown in the following diagram:

First, we have assigned the value 25 to a (a variable whose address in memory we have assumed to be 1776). The second statement copied to c the content of variable a (which is 25). This is a standard assignment operation, as we have done so many times before. Finally, the third statement copies to b not the value contained in a but a reference to it (i.e., its address, which we have assumed to be 1776). The reason is that in this third assignment operation we have preceded the identifier a with the reference operator (&), so we were no longer referring to the value of a but to its reference (its address in memory).

Dereference operator (*)


Using a pointer we can directly access the value stored in the variable which it points to. To do this, we simply have to precede the pointer's identifier with an asterisk (*), which acts as dereference operator and that can be literally translated to "value pointed by". A=25; B=&a; C=*B; The first expression assigns on a 25. The second one uses the reference operator (&), which returns the address of variable a, into b. The third expression uses the dereference operator (*) that, can read as "value pointed by", and the value pointed by b is indeed 25.

Pointers and arrays


Pointers can also be used to store the address of an array. When we store address of an array in pointer it is equivalent to the address of the first element that it points to. For example, supposing these two declarations:

1 int numbers [20]; 2 int * p;

The following assignment operation would be valid:

p = numbers;
After the above statement the pointer p will store the address of the first element of the array. 1776 1778 1780 1782 1784

P= 1776
#include <iostream> void main () { int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) { cout << numbers[n] << ", "; } } Output: 10, 20, 30, 40, 50,

Pointer arithmetics
To conduct arithmetical operations on pointers is a little different than to conduct them on regular integer data types. Only addition and subtraction operations are allowed to be conducted with pointers. But both addition and subtraction have a different behavior with pointers according to the size of the data type to which they point. As different fundamental data types, occupy different space in the memory. For example, char takes 1 byte, short takes 2 bytes and long takes 4. Suppose that we define three pointers :

1 char *mychar; 2 short *myshort; 3 long *mylong;


Suppose they point to memory locations 1000, 2000 and 3000 respectively. So if we write:

1 mychar++; 2 myshort++; 3 mylong++; mychar, as you may expect, would contain the value 1001. But not so obviously, myshort would contain the value 2002, and mylong would contain 3004, even though they have each been increased
only once. The reason is that when adding one to a pointer we are making it to point to the following element of the same type with which it has been defined, and therefore the size in bytes of the type pointed is added to the pointer.

Pointers to pointers
C++ allows the use of pointers that point to pointers, that these, in its turn, point to data (or even to other pointers). In order to do that, we only need to add an asterisk (*) for each level of reference in their declarations:

1 2 3 4 5 6

char a; char * b; char ** c; a = 'z'; b = &a; c = &b;

This could be represented as:

#include <iostream> void main () { int a=25; int * b;

int **c; b=&a; c=&b; cout << a << endl; cout<<b<<endl; cout<<c<<endl; } Output: 25 7230
8092

Pointers to functions
C++ allows operations with pointers to functions. They are used passing a function as an argument to another function, as they cannot be passed as such. In order to declare a pointer to a function we have to declare it like the prototype of the function except that the name of the function is enclosed between parentheses () and an asterisk (*) is inserted before the name:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

#include <iostream> int addition (int a, int b) { return (a+b); } int subtraction (int a, int b) { return (a-b); } int operation (int x, int y, int(*functocall)(int,int)) { int g; g = (*functocall)(x,y); return (g); } void main () { int m,n; int (*minus)(int,int) = subtraction; m = operation (7, 5, addition); n = operation (20, m, minus); cout <<n; }

Here in the main function, "m = operation (7, 5, addition);" shows that addition function is passed in as a parameter. Next line "n = operation (20, m, minus);" shows that a function pointer "minus" which points to subtraction function is passed in as a parameter. In the example, minus is a pointer to a function that has two parameters of type int. It is immediately assigned to point to the function subtraction, all in a single line:

int (* minus)(int,int) = subtraction;

void pointers
The void type of pointer is a special type of pointer. In C++, void represents the absence of type, so void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereference properties). This allows void pointers to point to any data type,

from an integer value or a float to a string of characters. But in exchange they have a great limitation: the data pointed by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason we will always have to cast the address in the void pointer to some other pointer type that points to a concrete data type before dereferencing it.

(string.h)
Functions
Copying: memcpy Copy block of memory (function ) memmove Move block of memory (function ) strcpy Copy string (function ) strncpy Copy characters from string (function ) Concatenation: strcat Concatenate strings (function ) strncat Append characters from string (function ) Comparison: memcmp Compare strcmp Compare strcoll Compare strncmp Compare Searching: strchr Locate first occurrence of character in string (function ) strstr Locate substring (function ) Other: strlen Get string length (function )

two blocks of memory (function ) two strings (function ) two strings using locale (function ) characters of two strings (function )

(ctype.h)
Character handling functions This header declares a set of functions to classify and transform individual characters. Character classification functions They check whether the character passed as parameter belongs to a certain category: isalnum Check if character is alphanumeric (function ) isalpha Check if character is alphabetic (function ) isdigit Check if character is decimal digit (function )

islower Check if character is lowercase letter (function ) isspace Check if character is a white-space (function ) isupper Check if character is uppercase letter (function ) Character conversion functions Two functions that convert between letter cases: tolower Convert uppercase letter to lowercase (function ) toupper Convert lowercase letter to uppercase (function )

Abstract Base Classes


A pure virtual function is a function which does not have definition of its own. The classes which derive from this class need to provide definition for such function. A class containing at least one such pure virtual function is called as abstract base class. We can not create objects of abstract class because it contains functions which have no definition. We can create pointers and references to an abstract class. Consider example of base class Shape and derived classes Circle, Rectangle, triangle etc. The function Draw() is made pure virtual in the base class Shape. It is overridden by the derived classes. So the class Shape becomes abstract base class. class Shape { int x, y; public: virtual void draw() = 0; }; class Circle: public Shape { public: draw() { //Code for drawing a circle } }; class Rectangle: public Shape { Public: void draw() { //Code for drawing a rectangle } }; class Triangle: public Shape { Public: void draw() { //Code for drawing a triangle } };

virtual destructor
As you may know, in C++ a destructor is generally used to deallocate memory and do some other cleanup for a class object and its class members whenever an object is destroyed. Destructors are distinguished by the tilde, the ~ that appears in front of the destructor name. The need for virtual destructors is best illustrated by an example.
#include iostream.h class Base { public: Base(){ cout<<"Constructing Base";} ~Base(){ cout<<"Destroying Base";} }; class Derive: public Base { public: Derive(){ cout<<"Constructing Derive";} ~Derive(){ cout<<"Destroying Derive";} }; void main() { Base *basePtr = new Derive(); delete basePtr;

} The output :
Constructing Base Constructing Derive Destroying Base

we can see that the constructors get called in the appropriate order when we create the Derive class object pointer in the main function. But there is a major problem with the code above: the destructor for the "Derive" class does not get called at all when we delete basePtr. To overcome this problem we can do is make the base class destructor virtual, and that will ensure that the destructor for any class that derives from Base. So, the only thing we will need to change is the destructor in the Base class and heres what it will look like:
class Base { public: Base(){ cout<<"Constructing Base";} // this is a destructor: virtual ~Base(){ cout<<"Destroying Base";} };

The output :
Constructing Base Constructing Derive Destroying Derive Destroying Base

You might also like