tags:

views:

176

answers:

4

Yes i know the phrase "virtual constructor" makes no sense but i still see articles like this

one: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=184

and i'v heard it mentioned as a c++ interview.

What is the general consensus? Is a "Virtual Constructor" good practice or something to be avoided completely?

To be more more precise, can some one provide me with a real world scenario where they have had to use it, from where i stand this concept of virt. constr. is a somewhat useless invention but i could be wrong.


A: 

It's something you can use, but only when you really, really need it. Even the guy in the link said that it's only something that you use if desperate.

DeadMG
+1  A: 
Noah Roberts
+1  A: 

The best way to write "virtual constructors" is to use a Prototype pattern with a Clone() virtual method wich calls the copy constructor of the real type of the object and returns a pointer to a base class.


class Base
{
public:
    virtual Base*    Clone() { return new Base(*this); }
};

class Derived : public Base
{
    virtual Base*    Clone() { return new Derived(*this); }
};

It's not considered a good practice and is to use only if you need it (implement a copy-paste function for example)

Opera
+2  A: 

I consider these so-called "virtual constructors" a bad design when used instead of constructors. These are nothing but virtual functions that are supposed to be called at the beginning of use of an instance of a class.

From the link you've posted:

class Browser
{
public:
  //virtual default constructor
  virtual Browser* construct() {return new Browser;} 
};

Let's add a member field:

class Browser
{
  int member;
public:
  //virtual default constructor
  virtual Browser* construct() {return new Browser;} 
};

We need to initialize the member field, how do we do it?

class Browser
{
  int member;
public:
  //virtual default constructor
  virtual Browser* construct() 
  { 
    Browser* b = new Browser;
    b->member = 0;
    return b;
  } 
};

Consider a situation when someone forgets to use template <class T> void func(T & obj) and does something like this:

Browser b;
printf("member=%d", b.member);

This way an uninitialized field is used. There is no way to prevent it.

Now, in this case

class Browser
{
  int member;
public:
  Browser() : member(0) { }
  virtual Browser* construct() { /* some init stuff */ return new Browser;} 
};

the default constructor is always used and member field always initialized. However calling the construct() a "virtual constructor" I consider a naming abuse.

The pattern I showed above is quite common eg. in MFC. CWnd and similar classes use constructors to init instances and Create(...) functions to fully init and create controls. I would never call the Create(...) function a "virtual constructor", anyway.

AOI Karasu