[comp.lang.c++] Virtual Constructors

conrad@jupiter.ucsc.edu.UUCP (09/26/87)

Virtual constructors are not allowed.  So if I need a a copy
of a particular object which has derived classes, how do I
do it?  For example: rectangle, circle, line, etc. are derived
classes of the base class *shape*.  Now I want to make a copy
of a given shape.

franka@mmintl.UUCP (Frank Adams) (09/30/87)

In article <895@saturn.ucsc.edu> conrad@jupiter.ucsc.edu (Al Conrad) writes:
>Virtual constructors are not allowed.  So if I need a a copy
>of a particular object which has derived classes, how do I
>do it?  For example: rectangle, circle, line, etc. are derived
>classes of the base class *shape*.  Now I want to make a copy
>of a given shape.

class shape {
	virtual shape * copy();
}

class rectangle : public shape {
	shape * copy() {
		rectangle * answer = new rectangle;
		[copy this];
		return answer;
	}
}

If you really want a constructor, you can now add in class shape:

	shape(shape * original) {this = original->copy()};

Otherwise, you can just use the copy function.
-- 

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108

bs@alice.UUCP (10/01/87)

# From: conrad@jupiter.ucsc.edu.UUCP (conrad @ University of California, Santa Cruz; CIS/CE)
# Virtual constructors are not allowed.  So if I need a a copy
# of a particular object which has derived classes, how do I
# do it?  For example: rectangle, circle, line, etc. are derived
# classes of the base class *shape*.  Now I want to make a copy
# of a given shape.

I think you are just thinking about it a little bit wrong. YOU cannot
make a copy of something that you don't know the exact type of, but
with a little bit forethought you can ask IT to copy itself; after
all IT (and nobody else) knows exactly what kind of shape it is
(provided it has suitable virtual functions):

class shape {
	// ...
	virtual shape* copy();
};

class circle : public shape {
	// ...
	shape* copy() { return new circle(*this); }
};

class rectangle : public shape {
	// ...
	shape* copy() { return new rectangle(*this); }
};


my_program(shape* p)
{
	shape* p2 = p->copy();	// make a copy of p
	// ...
}

coatta@ubc-csgrads.uucp (Terry Coatta) (01/21/88)

There have been a couple of messages about virtual destructors recently.
I have two questions.  Can someone post (re-post) some example code which
uses virtual destructors and is there such a thing as virtual constructors?

Terry Coatta
Dept. of Computer Science, UBC, Vancouver BC, Canada
coatta@grads.cs.ubc.cdn

`What I lack in intelligence, I more than compensate for with stupidity'

 

mikem@otc.oz (Mike Mowbray) (02/04/88)

In article <1788@ubc-cs.UUCP>, coatta@ubc-csgrads.uucp (Terry Coatta) says:

 > Can someone post (re-post) some example code which uses virtual destructors

Here's a sketch of a library we use internally here. (Apologies if some of
the code isn't exactly right - it's just intended to convey the idea.)

Consider a linked list class where everything on the list is derived from a
"Dlink" class which has a virtual destructor:

	class Dlink
	{
		friend class Dlist;

		void	unlink();	// tidy up on either side

	    protected:
		Dlink  *prev, *next;
	    
		Dlink();		// set prev and next to null, say
		virtual ~Dlink();	// call unlink()
	};

	void Dlink::unlink()
	{
	    if (prev)
		prev->next = next;
	    if (next)
		next->prev = prev;
	    next=prev=NULL;
	}

	Dlink::~Dlink()
	{
	    unlink();
	}

	//------------------------------------------

	class Item1 : public Dlink
	{
		// .....
	    public:
		Item1();
		~Item1();		// do some other stuff to clean up

	class Item2 : public Dlink
	{
		// .....
	    public:
		Item2();
		~Item2();		// do some other stuff to clean up
	};
	//-------------------------------------------

	class Dlist
	{
		Dlink  key;
	    public:
		Dlist()		{ key.prev = key.next = &key; }
		~Dlist();	// Call the destructor for every Dlink on list

		void put(Dlink *d);
	};

	void Dlist::put(Dlink *d)
	{
	    d->unlink();		// for safety
	    d->prev = key->prev;
	    d->next = &key;
	    key->prev->next = d;
	    key->prev = d;
	}

	Dlist::~Dlist()
	{
	    while (key.next != &key)
		delete key.next;
	}
	//----------------------------------------------

Then you can put install Item1's and Item2's on a Dlist, and the correct
destructors will be called when the Dlist is deleted.

 > and is there such a thing as virtual constructors?

This would make no sense. A thing can't be created if one doesn't know exactly
(at compile time) what one wants to create.


			Mike Mowbray
		    Systems Development
			|||| OTC ||

		    ACSnet:  mikem@otc.oz
		      UUCP:  {uunet,mcvax}!otc.oz!mikem 
		     Phone:  (02) 287-4104
		     Snail:  GPO Box 7000, Sydney 2001, Australia