Sunteți pe pagina 1din 20

Polymorphism continued

Virtual Destructor:
A problem can occur when using polymorphism to process
dynamically allocated objects of a class hierarchy.
If we try to destroy a derived class object with a non-virtual
destructor by applying the delete operator to a base class
pointer to the object, only the base class destructor is called,
the destructor of the derived class is not called.
A simple solution to this is to create a virtual destructor
in the base class.
Now if an object in the hierarchy is destroyed explicitly by
applying the delete operator to a base-class pointer, the
destructor of the appropriate class is called.

class Base
// virtual destructor
{ public:
virtual ~Base()
{cout << Base class destroyed << endl;}
};

class Derv: public Base


{ public:
~Derv()
{cout << Derived class destroyed << endl;}
};
int main()
{ Base* pBase = new Derv;
delete pBase;
}

Run:
Derived class destroyed
Base class destroyed

Virtual Base Classes:


Virtual base classes are related to multiple inheritance.
Suppose we have a base class, Base; two derived classes
Derv1 and Derv2; and a fourth class Dervnew, derived
from both Derv1 and Derv2.
In this case, if a member function in Dervnew class
wants to access data or function in the Base class, an
errors occurs.
This is because Dervnew inherits copies of both Derv1
and Derv2; therefore, when Dervnew access base class
data, it is ambiguous which copy should it access.

class Base
// ambiguous reference to base class
{ protected:
int basedata;
public: Base(): basedata(0)
{
}
};
class Derv1: public Base
{ };
class Derv2: public Base
{ };
class Dervnew: public Derv1, public Derv2
{ public:
void getdata()
{cout << "basedata = " << basedata << endl;}
//Error: reference to basedata is ambiguous
};
int main()
{ Dervnew* nptr;
nptr = new Dervnew;
nptr -> getdata();
}

To eliminate this ambiguity, we make Derv1 and Derv2


into virtual base classes.
The use of the keyword virtual in these two classes
causes them to share a single common subobject of their
base class Derv.
Since now there is only one copy of basedata, there is no
ambiguity when it is referred to in the Dervnew.

class Base
// virtual base classes
{ protected:
int basedata;
public:
Base(): basedata(0)
{
}
};
class Derv1: virtual public Base
{ };
class Derv2: virtual public Base
{ };
class Dervnew: public Derv1, public Derv2
{ public:
void getdata()
{cout << "basedata = " << basedata << endl;}
};
int main()
{ Dervnew* nptr;
nptr = new Dervnew;
nptr -> getdata();
}

Run:
basedata = 0

Linked Lists
A data structure is a particular way of storing and
organizing data in a computer so that it can be used
efficiently.
A data structure in which data items are arranged in a
linear order is called a linear data structure or a linear
list (or a list).
Examples of linear data structures are:
1. Arrays: statically allocated or dynamically allocated.
2. Linked Lists: dynamically allocated.
Linked lists represent dynamic data-structures that grow
and shrink during execution.

In a linked list, items may be present in the memory


anywhere. Associated with each item is a link or pointer
to the next item
Insertion and removal can take place anywhere in a linked
list.

Self-Referential Classes:

A self-referential class contains a pointer member that


points to an object of the same class type.
For example the following class is a self referential class:
class Node
{private: int data;
Node *nextPtr;
public:
Node(int);
void setData(int);
voidGetData() const;
void setNextPtr(Node*);
Node* getNextptr() const;
};

The class Node has two private data members integer


member data and a pointer member nextPtr.

The member nextPtr is referred to as a link it ties an


object of type Node to another object of same type :

15

10

Self-referential classes can be used to form linear data


structures such as linked lists.

(Singly) Linked Lists:


A (singly) linked list is a linear collection of selfreferential class objects, called nodes, connected by
pointer links.
Thus a node consists of two halves the data half, which
contains one or more data fields, and the pointer half,
which contains a pointer that points to the next node in
the linked list.
node

Data
Members

pointer

A linked list is accessed via a pointer to the lists first


node. This pointer is called the head.
Each subsequent node is accessed via the link pointer
member stored in the previous node.
The link pointer in the last node of a list is set to null (0)
to mark the end of the list.
Data is stored in a linked list dynamically each node is
created as necessary, and may be deleted when not
required.
A node can contain data of any type, including objects of
other classes.

A
Head

Insertion and deletion of an element in a linked list can be


done as follows.
Suppose we have the following linked list:
Bat

Cat

Fat

Hat

We can an insert a data item Gat between Fat and Hat as


follows:
Get a node a that is currently unused.
Set the data field of a to Gat
Set the link field of a to a point to the node after Fat, which
contains Hat.
Set the link field of the node containing Fat to a.

Bat

Cat

Fat

Hat

Gat

Similarly the node Gat can be deleted as follows:

Bat

Cat

Fat

Gat

Hat

Defining a Node:
A node can be defined as follows:
class Node
{private:
int data;
// data item
Node *nextPtr; // link to next node
public:
...
};

Designing a Linked List:


A linked list is a chain of nodes. The linked list itself is
accessed by a pointer to the first node. For example,
Node* head;

The following example illustrates how a linked list can be


defined:

class SLL;

// forward declaration

class Node
{private:
int data;
// data item
Node *nextPtr; // link to next node
public:
friend class SLL;
...
};
class SLL
{private:
Node *head;
//pointer to the first node
public:
//operations for manipulating the linked list
...
};

Creating a Linked List:


To create an empty linked list, we only need to assign the
head pointer the value NULL.
This is usually done by the default constructor:
class SLL
{private:
Node *head;
public:
SLL()
{ head = NULL;
};

The following program illustrates the creation of a linked


list with three nodes:

struct Node // creating a linked list


{ int value;
Node *next;
};
class SLL
{ private:Node *head;
public:
SLL ()
{ head = NULL; }
void appendNode (); //function to add a new node
void displayList(); };
void SLL :: appendNode ()
{ Node *newNode1,*newNode2,*newNode3;
newNode1 = new Node;
newNode2 = new Node;
newNode3 = new Node;
newNode1 -> value = 22;
//puts value 22 in first node
newNode1 -> next = NULL;
newNode2 -> value = 33;
newNode2 -> next = NULL;
newNode3 -> value = 44;

newNode3 -> next = NULL; //three nodes with next pointers NULL
head=newNode1;
newNode1->next=newNode2;
newNode2->next=newNode2;
}
void SLL :: displayList ()
{ Node *nodePtr;
nodePtr = head;
while(nodePtr != NULL)
{cout<<nodePtr -> value<<endl;
nodePtr = nodePtr -> next;}
}
int main()
{
SLL list;
list.appendNode ();
cout<<"List is being displayed."<<endl;
list.displayList();
}

Run:
List is being displayed.
22
33
44

In the above program, struct type can be replaced by a


Node class as follows:
class Node
{ private:
int value;
Node *next;
public:
Node():value(0)
{ }
friend class SLL;
};

S-ar putea să vă placă și