Ask question, find answer on any topic in real time from people around the world. Have a question ? Ask now. Know an Answer share your Knowledge to world.PrepJunk is the online community that has Junk of answers!

What is a ‘virtual constructor’?

0

What is a ‘virtual constructor’?

asked Apr 7, 2012 in C++ by mohan (541 points)
    

1 Answer

0

Technically speaking, there is no such thing. You can get the effect you desire by a virtual ‘clone()’ member fn (for copy constructing), or a ‘fresh()’ member fn (also virtual) which constructs/creates a new object of the same class but is ‘fresh’ (like the ‘default’ [zero parameter] ctor would do).

The reason ctors can’t be virtual is simple: a ctor turns raw bits into a living object. Until there’s a living respondent to a message, you can’t expect a message to be handled ‘the right way’. You can think of ctors as ‘class’ [static] functions, or as ‘factories’ which churn out objects. Thinking of ctors as ‘methods’ attached to an object is misleading.

Here is an example of how you could use ‘clone()’ and ‘fresh()’ methods:

class Set { //normally this would be a template
public:
virtual void insert(int); //Set of ‘int’
virtual int remove();
//...
virtual Set& clone() const = 0; //pure virtual; Set is an ABC
virtual Set& fresh() const = 0;
virtual ~Set() { } //see on ‘virtual destructors’ for more
};

class SetHT : public Set {
//a hash table in here
public:
//...
Set& clone() const { return *new SetHT(*this); }
Set& fresh() const { return *new SetHT(); }
};

‘new SetHT(...)’ returns a ‘SetHT’, so ‘new’ returns a SetHT&. A SetHT is-a Set, so the return value is correct. The invocation of ‘SetHT(this)’ is that of copy construction (‘this’ has type ‘SetHT&’). Although ‘clone()’ returns a new SetHT, the caller of clone() merely knows he has a Set, not a SetHT (which is desirable in the case of wanting a ‘virtual ctor’). ‘fresh()’ is similar,
but it constructs an ‘empty’ SetHT.

Clients can use this as if they were ‘virtual constructors’:

void client_code(Set& s)
{
Set& s2 = s.clone();
Set& s3 = s.fresh();
//...
delete &s2; //relies on destructor being virtual!!
delete &s3; // ditto
}

This fn will work correctly regardless of how the Set is implemented (hash
table based, AVL tree based, etc).

See above on ‘separation of interface from implementation’ for more.

answered Apr 7, 2012 by mohan (541 points)