When Do We Need to Have a Default Constructor

When do we need to have a default constructor?

A default constructor is not synthesised if you created your own constructor with arguments. Since you gave Shape a constructor of your own, you'd have to explicitly write out a default Shape constructor now:

class Shape
{
int k;

public:
Shape() : k(0) {}
Shape(int n) : k(n) {}
~Shape() {}
};

(You can leave out the empty ~Rect() {} definitions, as these will be synthesised.)

However, it looks to me like you don't want a default constructor for Shape here. Have Rect construct the Shape base properly:

class Shape
{
int area; // I've had to guess at what this member means. What is "k"?!

public:
Shape(const int area)
: area(area)
{}
};

class Rect : public Shape
{
int l;
int w;

public:
Rect(const int l, const int w)
: Shape(l*w)
, l(l)
, w(w)
{}
};

Also note that this example is oft cited as an abuse of OO. Consider whether you really need inheritance here.

Do I really need to define default constructor in java?

A default (no-argument) constructor is automatically created only when you do not define any constructor yourself.

If you need two constructors, one with arguments and one without, you need to manually define both.

Should i define the default constructor?

This is likely to be closed as "primarily opinion-based," but I can give you some objective points to consider:

  • If you don't define the default constructor, and someone later adds a constructor with parameters and forgets to also add the parameterless constructor, the default constructor will go away and that could break existing code. Explicitly defining it ensures that even if someone adds an overloaded constructor later, the parameterless one is still there.

  • If the constructor is declared in the header and defined out-of-line (in a .cc/.cpp file), then the implementation can later be modified with dependent code only needing to be re-linked. Declaring a constructor after the fact necessarily affects the header, requiring recompilation of dependent code.

    • An empty out-of-line constructor will still need to be called, incurring a small run-time cost, whereas with an implicitly provided default constructor the compiler can see that nothing needs to be done and avoid the call.

  • Defining it explicitly requires more typing and results in more lines of code. There is a small but nonzero cost associated with this (time taken to type it in, and time taken for readers of the code to read through it).

  • Defining it explicitly disqualifies the class from being an aggregate class, unless you use =default in C++11.

Yes, these points are contradictory. I think you will find that the prevailing opinion is not to define it explicitly, but as far as the language is concerned there is no correct or incorrect way. (Unless you need your type to be an aggregate.)

When is mandatory to have a default constructor along with parameterized constructor in Java?

The compiler doesn't ever enforce the existence of a default constructor. You can have any kind of constructor as you wish.

For some libraries or frameworks it might be necessary for a class to have a default constructor, but that is not enforced by the compiler.

The problem you might be seeing is if you have a class with a custom constructor and you don't have an implicit super() call in your constructor body. In that case the compiler will introduce a call to the super classes default constructor. If the super class doesn't have a default constructor then your class will fail to compile.

public class MyClass extends ClassWithNoDefaultConstructor
public MyClass() {
super(); //this call will be added by the compiler if you don't have any super call here
// if the super class has no default constructor the above line will not compile
// and removing it won't help either because the compiler will add that call
}
}

Should we always include a default constructor in the class?

You have to keep in mind that if you don't provide an overloaded constructor, the compiler will generate a default constructor for you. That means, if you just have

public class Foo
{
}

The compiler will generate this as:

public class Foo
{
public Foo() { }
}

However, as soon as you add the other constructor

public class Foo
{
public Foo(int x, int y)
{
// ...
}
}

The compiler will no longer automatically generate the default constructor for you. If the class was already being used in other code which relied on the presence of a default constructor, Foo f = new Foo();, that code would now break.

If you don't want someone to be able to initialize the class without providing data you should create a default constructor which is private to be explicit about the fact that you are preventing instances from being constructed with no input data.

There are times, however, when it is necessary to provide a default constructor (whether public or private). As was previously mentioned, some types of serialization require a default constructor. There are also times when a class has multiple parameterized constructors but also requires "lower level" initialization, in which case a private default constructor can be used which is chained in from the parameterized constructors.

public class Foo
{
private Foo()
{
// do some low level initialization here
}

public Foo(int x, int y)
: this()
{
// ...
}

public Foo(int x, int y, int z)
: this()
{
// ...
}
}


Related Topics



Leave a reply



Submit