Why cant we use virtual constructors in C++? :-|

Recommended Answers

All 5 Replies

I've moved this thread to the C and C++ forum. :)

>Why cant we use virtual constructors in C++?
Because a virtual constructor is nonsensical.

Virtual Constructor is also a technique developed by Jim Coplien (see book Advanced C++ style and Idioms).

Basically this depends on the ability to re-use a memory address to construct another object, here is an example.
Say I have a memory address representing a BIOS data, e.g. date/time
structure. To directly represent this memory location as an object BIOSDateTime I can construct it on that location by using following syntax :

BIOSDateTime *bT= new (BIOSLOCATION)BIOSDateTime();

prior to above call BIOSLOCATION would have been declared with the
memory address.

#define BIOSLOCATION ((void*)0x0000ff33;

The perspective is that no memory allocation is done only constructor gets called.

Why would you do that, well to have a more cleaner code.

class BIOSDateTime 
{
   long  _t;
   public:
    long GetCurrentTime() 
    {
        return _t;
    }
};

e.g. we can write

bT->GetCurrentTime();

and it will return current time.


BTW, above is a completely pseudo code, I haven't done any programming at BIOS for a long long long time.

But you get the picture, from above method we will know the hardware date/time in real-time.

Now comes the fun part, Coplien used this perspective to
construct an object at runtime from within a base class (or any other
derived class, but actual class is constructed at runtime).

Where would you use it, where you don't know which object may be instantiated in advance and the cost of knowing that will incur performance hit.

For example a software that has to process different communication
packets and take action on it, here you want a progressive construction of the concrete packet class, but you don't want one monlithic function to interepret each and every special packet.
it assumes that the packets are following an Envelop / Letter pattern, i.e.
concrete packets are enveloped within a base packet.

so

class BasePacket
{
char _maxbuffer[MAX_LEN];

virtual void DoSomething()
{
}
public:
  BasePacket();  //see implementation later
}
class IP:BasePacket
{
  //known IP member variables here
  public:
    IP();
  virtual void DoSomething();
}

class UDP:IP
{
//known UDP member variables here (NOTE: the member variable have to map exactly with the memory buffer and packet standard)

  public :
   UDP();
  virtual void DoSomething();
}
class TCP:UDP
{
// TCP members here
public:
    TCP();

  virtual void DoSomething();
}

At the arrival of a buffer at a known address, one will
construct BasePacket()

void *pDMABuffer=0x0033030;

BasePacket *packet= new (pDMABuffer) BasePacket();

packet->DoSomething();

And here is the Virtual Constructor :


BasePacket():BasePacket()
{
   if(_buffer[0]=="IP")
       new (this) IP();
   else
      throw "invalid packet";
}


IP:IP()
{
  if(_buffer[1]=="UDP")
      new (this) UDP();
  else ... ICMP, etc....
}


UDP:UDP()
{
  if(_buffer[2]=="TCP")
     new (this) TCP();
 ...
 ...

}

Again, all is pseudo code.
But you get the picture.

Coplien went on to use it in implementing an expression parser, which I think is another excellent example of using virtual constructor.

But notice this has nothing to do with using 'virtual' keyword at constructor, that is as said by someone non-sensical.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.