Home arrow C++ Programming arrow Introduction to Templates

Language Translator

Hacking Zone

Hacking Tools
Attacking

Configure Windows

Windows Configuration

Novels

Mix Novels

Human Personality

Body Language
Introduction to Templates PDF Print E-mail
Written by Hemanshu Patel   
Wednesday, 24 October 2007
Article Index
Introduction to Templates
Page 2
Page 3
Page 4
Page 5
Page 6
Page 7
Page 8
Page 9
 


Turning ownership on and off

Let&rsquos return to the ownership problem. Containers that hold objects by value don&rsquot usually worry about ownership because they clearly own the objects they contain. But if your container holds pointers (which is more common with C++, especially with polymorphism), then it&rsquos very likely those pointers may also be used somewhere else in the program, and you don&rsquot necessarily want to delete the object because then the other pointers in the program would be referencing a destroyed object. To prevent this from happening, you must consider ownership when designing and using a container.

Many programs are much simpler than this, and don&rsquot encounter the ownership problem: One container holds pointers to objects that are used only by that container. In this case ownership is very straightforward: The container owns its objects.

The best approach to handling the ownership problem is to give the client programmer a choice. This is often accomplished by a constructor argument that defaults to indicating ownership (the simplest case). In addition there may be &ldquoget&rdquo and &ldquoset&rdquo functions to view and modify the ownership of the container. If the container has functions to remove an object, the ownership state usually affects that removal, so you may also find options to control destruction in the removal function. You could conceivably add ownership data for every element in the container, so each position would know whether it needed to be destroyed; this is a variant of reference counting, except that the container and not the object knows the number of references pointing to an object.

//: C16:OwnerStack.h 

>// Stack with runtime conrollable ownership

>#ifndef OWNERSTACK_H


>#define OWNERSTACK_H


>


>template<class T> class Stack {


> struct Link {


> T* data;


> Link* next;


> Link(T* dat, Link* nxt)


> : data(dat), next(nxt) {}


> }* head;


> bool own;


>public:


> Stack(bool own = true) : head(0), own(own) {}


> ~Stack();


> void push(T* dat) {


> head = new Link(dat,head);


> }


> T* peek() const {


> return head ? head->data : 0;


> }


> T* pop();


> bool owns() const { return own; }


> void owns(bool newownership) {


> own = newownership;


> }


> // Auto-type conversion: true if not empty:

> operator bool() const { return head != 0; }


>};


>


>template<class T> T* Stack<T>::pop() {


> if(head == 0) return 0;


> T* result = head->data;


> Link* oldHead = head;


> head = head->next;


> delete oldHead;


> return result;


>}


>


>template<class T> Stack<T>::~Stack() {


> if(!own) return;


> while(head)


> delete pop();


>}


>#endif // OWNERSTACK_H ///:~

The default behavior is for the container to destroy its objects but you can change this by either modifying the constructor argument or using the owns( ) read/write member functions.

As with most templates you&rsquore likely to see, the entire implementation is contained in the header file. Here&rsquos a small test that exercises the ownership abilities:

//: C16:OwnerStackTest.cpp 

>//{L} AutoCounter

>#include "AutoCounter.h"

>#include "OwnerStack.h"

>#include "../require.h"

>#include <iostream>


>#include <fstream>


>#include <string>


>using namespace std;


>


>int main() {


> Stack<AutoCounter> ac; // Ownership on

> Stack<AutoCounter> ac2(false); // Turn it off

> AutoCounter* ap;


> for(int i = 0; i < 10; i++) {


> ap = AutoCounter::create();


> ac.push(ap);


> if(i % 2 == 0)


> ac2.push(ap);


> }


> while(ac2)


> cout << ac2.pop() << endl;


> // No destruction necessary since

> // ac "owns" all the objects

>} ///:~

The ac2 object doesn&rsquot own the objects you put into it, thus ac is the &ldquomaster&rdquo container which takes responsibility for ownership. If, partway through the lifetime of a container, you want to change whether a container owns its objects, you can do so using owns( ).

It would also be possible to change the granularity of the ownership so that it is on an object-by-object basis, but that will probably make the solution to the ownership problem more complex than the problem.



Last Updated ( Wednesday, 24 October 2007 )
 
< Prev   Next >
Your Ad Here

Donate us!!

Enter Amount:

RSS socialnet

Add to MyYahoo!
Subscribe in NewsGator Online
Add to Newsburst
Add to Google
Add to My AOL
Add to Pluck
Subscribe in FeedLounge
Add to Windows Live
Add to NetVibes
Subscribe in Rojo
Subscribe in Bloglines
Add to MyMSN
Add to Plusmo for your cellphone
Add to PageFlakes
Add to Technorati
Add to BlinkBits