Why Do We Not Have a Virtual Constructor in C++

No Virtual constructors but virtual destructor

  • There is no point in virtual constructor - you declare exactly what
    type is created, and it is well known in compile time. The compiler
    do not need [and actually cannot, since the dynamic dispatch is based
    on information which is created only after the object was created].
    So there are no virtual constructors.
  • Virtual destructors are important to prevent memory leaks, and
    monitor the system. Assume you have A* a = new B; [B inherits
    from A], and you later delete a; - the compiler has no way of
    knowing a is a B [in the general case], and will invoke A's
    destructor - if it wasn't virtual, and you might get a memory leak,
    or other faults.
  • Using virtual destructor - you ensure that B's destructor is
    invoked, since a B object is being destroyed
    .

In .NET can a class have virtual constructor?

no, a class cannot have a virtual constructor.

It doesn't make sense to have a virtual constructor. The order in which objects are constructed in C# is by constructing derived classes first, so the derived constructor is always called since the class you want to call is well known at the time of construction.

The other thing is, if you actually type this code out, you can quickly see that it makes very little sense at all

If you had:

public class BaseClass 
{
public virtual BaseClass()
{
}
}

and then

public class InheritedClass : BaseClass
{
//overrides baseclass constructor but why would you do this given that the
//constructor is always going to be called anyway??
public override InheritedClass()
{
}
}

(Why) Is virtual base class constructor call required in pure virtual derived class?

Design issues (which clearly exist here) aside, I fully agree with your reasoning that, because Left is an abstract class, no Left constructor will ever have to call any Base constructor and thus it is odd that it is required.

In fact, I tested your code with several compiler versions and it does compile just fine with gcc 7.1 and onwards, with clang 3.4.1 and onwards, and with all available msvc versions.

So, my assumption is, that this was just a bug in earlier compiler versions. Can anyone confirm this?

Also note, if you change virtual void leftsMethod() = 0; to virtual void leftsMethod() {}, so that Left is not abstract anymore, the error returns, even with the latest versions. And this makes perfectly sense, as now you could instantiate a Left instance and thus it would be up to Left's constructor to call one of Base's constructors.

Possible workaround

If you cannot switch to a newer compiler and if you cannot alter the implementation of Base, this may be a working solution for you:

Define a dummy instance of CustomType somewhere. Then, you can provide the "required" default constructors like this:

class CustomType{};

class Base
{
public:
Base( CustomType& obj ) : refObj_( obj ) {}
private:
CustomType& refObj_;
};

static CustomType dummy;

class Left : public virtual Base
{
protected:
Left() : Base(dummy) {}; // note here
public:
virtual void leftsMethod() = 0;
};

class Right : public virtual Base
{
protected:
Right() : Base(dummy) {}; // and here
public:
virtual void rightsMethod() = 0;
};

class Bottom : public Left, public Right
{
public:
Bottom( CustomType& obj ) : Base( obj ), Left(), Right() {}
virtual void leftsMethod() override {}
virtual void rightsMethod() override {}
};

void test()
{
CustomType c;
Bottom b(c);
}

This is just to make the compiler happy, your argument that these constructors will never call Base(dummy) still holds.

Note however, that Base should really have a virtual destructor! I don't know if you just didn't include it here for brevity or if it really doesn't have one. If it doesn't, it's a very bad idea to build a class hierarchy on top of it.

Constructors and destructor must be virtual?

You cannot have Virtual constructor in C++ why no virtual Constructor.

Virtual destructors are useful when you can delete an instance of a derived class through a pointer to base class. Refer to When to use Virtual Destructor.

Is using a C++ Virtual Constructor generally considered good practice?

All the author has done is implement prototyping and cloning. Both of which are powerful tools in the arsenal of patterns.

You can actually do something a lot closer to "virtual constructors" through the use of the handle/body idiom:



struct object
{
void f();
// other NVI functions...
object(...?);
object(object const&)
object& operator = (object const&);
~object();

private:
struct impl;
impl * pimpl;
};

struct object::impl
{
virtual void f() = 0;
virtual impl* clone() = 0;
// etc...
};

struct impA : object::impl { ... };
struct impB : object::impl { ... };

object::object(...?) : pimpl(select_impl(...?)) {}
object::object(object const& other) : pimpl(other.pimpl->clone()) {}

// etc...

Don't know if anyone has declared this an Idiom but I've found it useful and I'm sure others have come across the same idea themselves.

Edit:
You use factory methods or classes when you need to request an implementation for an interface and do not want do couple your call sites to the inheritance tree behind your abstraction.

You use prototyping (clone()) to provide generic copying of an abstraction so that you do not have to determine type in order to make that copy.

You would use something like I just showed for a few different reasons:

1) You wish to totally encapsulate the inheritance relation behind an abstraction. This is one method of doing so.

2) You want to treat it as a value type at the abstract level (you'd be forced to use pointers or something otherwise)

3) You initially had one implementation and want to add new specifications without having to change client code, which is all using the original name either in an auto declaration or heap allocation by name.



Related Topics



Leave a reply



Submit