168

In C#, C++ and Java, when you create a constructor taking parameters, the default parameterless one goes away. I have always just accepted this fact, but now I've started wondering why.

What is the reason for this behavior? Is it just a "safety measure/guess" saying "If you've created a constructor of your own, you probably don't want this implicit one hanging around"? Or does it have a technical reason that makes it impossible for the compiler to add one once you have created a constructor yourself?

olagjo
  • 2,125
  • 2
  • 14
  • 16
  • 7
    You can add C++ to the list of languages that have this behaviour. – H H Aug 03 '12 at 09:11
  • 18
    And in C++ you can now say `Foo() = default;` to get the default one back. – MSalters Aug 03 '12 at 09:35
  • 1
    If your constructor with parameters can have default arguments for all its parameters, then it would conflict with the built-in parameterless constructor, hence the need to delete it when you create your own. – Morwenn Aug 03 '12 at 14:13
  • 3
    Imagine being present for this debate between the founders of the first compiler to make the default constructor requirement and the heated discussion it would have inspired. – kingdango Aug 07 '12 at 17:48
  • 7
    @HenkHolterman C++ isn't just another with this behaviour, but the originator, and it's to allow C compatibility, as discussed by Stroustrup in *The Design and Evolution of C++* and as summarised in my updated answer. – Jon Hanna Aug 09 '12 at 12:58
  • 1
    @kingdango No heated discussion, it was Stroustrup alone in his office writing some macros. Read the book I mention in my reply to Henk. – Jon Hanna Aug 09 '12 at 14:14

11 Answers11

228

There's no reason that the compiler couldn't add the constructor if you've added your own - the compiler could do pretty much whatever it wants! However, you have to look at what makes most sense:

  • If I haven't defined any constructor for a non-static class, I most likely want to be able to instantiate that class. In order to allow that, the compiler must add a parameterless constructor, which will have no effect but to allow instantiation. This means that I don't have to include an empty constructor in my code just to make it work.
  • If I've defined a constructor of my own, especially one with parameters, then I most likely have logic of my own that must be executed on creating the class. If the compiler were to create an empty, parameterless constructor in this case, it would allow someone to skip the logic that I had written, which might lead to my code breaking in all number of ways. If I want a default empty constructor in this case, I need to say so explicitly.

So, in each case, you can see that the behaviour of current compilers makes the most sense in terms of preserving the likely intent of the code.

Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
  • 2
    I think the rest of your answer pretty much proves your first sentence wrong. – Konrad Rudolph Aug 03 '12 at 16:58
  • 76
    @KonradRudolph, the first sentence says a compiler *could* add a constructor in this scenario - the rest of the answer explains why it doesn't (for the languages specified in the question) – JohnL Aug 03 '12 at 17:51
  • 1
    Well no. If we designed an OO language from scratch, the most obvious meaning of there being no constructor is, "you neglected to add a constructor that ensures the class' invariant" and it would raise a compilation error. – Jon Hanna Aug 26 '12 at 12:23
71

There's certainly no technical reason why the language has to be designed this way.

There are four somewhat-realistic options that I can see:

  1. No default constructors at all
  2. The current scenario
  3. Always providing a default constructor by default, but allowing it to be explicitly suppressed
  4. Always providing a default constructor without allowing it to be suppressed

Option 1 is somewhat attractive, in that the more I code the less often I really want a parameterless constructor. Some day I should count just how often I actually end up using a default constructor...

Option 2 I'm fine with.

Option 3 goes against the flow of both Java and C#, for the rest of the language. There's never anything that you explicitly "remove", unless you count explicitly making things more private than they would be by default in Java.

Option 4 is horrible - you absolutely want to be able to force construction with certain parameters. What would new FileStream() even mean?

So basically, if you accept the premise that providing a default constructor makes sense at all, I believe it makes a lot of sense to suppress it as soon as you provide your own constructor.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    I like option 3, because when I am writing something, I need more often to have both types of constructors then just constructor with parameter. So I would rather once a day make some parameterless constructor private then write 10 times a day parameterless constructors. But thats probably just me, I am writing lot of seriaziable classes... – Petr Mensik Aug 03 '12 at 08:47
  • 8
    @PetrMensik: If your parameterless constructor really needs to do absolutely nothing, it's a one-liner which surely wouldn't take much more code than an "explicit removal" statement. – Jon Skeet Aug 03 '12 at 08:50
  • 1
    That's right but I was talking about what in my opinion people need more often and that's both type of contructors. So option three is really souds really nice for me:) – Petr Mensik Aug 03 '12 at 08:55
  • 2
    @PetrMensik: Sorry, my mistake, yes. That's definitely the opposite of my experience - and I'd argue that including something automatically is the more *dangerous* option too... if you accidentally end up not excluding it, you can screw up your invariants etc. – Jon Skeet Aug 03 '12 at 08:56
  • 1
    Sounds reasonable, no compiler will ever force to make some constructor private, so it makes sense from security perspective (which is more important then my convienience of course:)) – Petr Mensik Aug 03 '12 at 09:01
  • 1
    There are plenty of cases where you (or your libraries) need the parameterless constructor: when you use reflection, dependancy injection, mapping to a DB, serialization and so on – PPC Aug 03 '12 at 17:15
  • @PPC: Reflection: provide the constructor arguments. Dependency injection: I tend to use dependency injection *via constructor parameters*. Serialization is the biggie, but I'd still rather be explicit in those cases. – Jon Skeet Aug 03 '12 at 17:17
  • Another option would be no default constructor for final classes and the current scenario for nonfinal classes. A class without constructors can not be extended and is thus effectively final. – emory Aug 03 '12 at 17:53
  • @emory: A class without any constructors can't be instantiated either - in which case in C# you'd make it a static class anyway, whereupon you *don't* get any constructors. – Jon Skeet Aug 03 '12 at 18:00
  • @JonSkeet I was thinking in java wrt classes with only static methods like `java.lang.Math` but I have thought of a use case (in java) for a uninstantiable class without static method. http://ideone.com/MqBkw - which is an argument for option 1. – emory Aug 03 '12 at 18:19
  • 1
    @emory: That seems like a pretty obscure use case to base a language design decision on though... – Jon Skeet Aug 03 '12 at 18:40
  • 2
    #4 is the case with C# `struct`s, for better or worse. – Jay Bazuzi Aug 03 '12 at 19:06
  • 4
    I like option 1 because it's easier to understand. No "magic" constructor that you can't see in the code. With option 1 the compiler should emit a warnig when (or maybe even disallow?) a non-static class has no instance constructors. How about: "No instance constructors found for class . Did you mean to declare the class static?" – Jeppe Stig Nielsen Aug 04 '12 at 11:27
  • @JeppeStigNielsen: Yes, that would make a lot of sense. – Jon Skeet Aug 04 '12 at 12:37
  • Option 1 could become really ugly when creating anonymous classes. – Lie Ryan Aug 09 '12 at 11:54
  • @JayBazuzi I like option 1 too (anonymous class construction wouldn't be an issue because there's already enough automatic code special to them that a bit more wouldn't hurt), but it would have made C++ incompatible with C, which would have prevented it gaining a foothold in lots of C houses, which could have meant it didn't have the impact it did, which could have meant it didn't end up influencing Java an C#, which could have meant we'd be talking about the legacy of some Smalltalk artifact on Java and Smalltalk# instead :) – Jon Hanna Aug 09 '12 at 14:11
  • 1
    @JayBazuzi: I don't think of .net structs has having a default constructor; rather, I think of them as coming into existence without running any constructor. Note that defining a struct in .net actually defines both a value type and a class type, with an implicit (widening) conversion from the former to the latter [called "boxing"], and an available explicit (narrowing) conversion from the latter to the former [called "unboxing"]. The class type associated with a value type does have a default constructor available, to allow for the creation of boxed instances via reflection. – supercat Aug 20 '12 at 05:11
  • @JonSkeet - "Some day I should count just how often I actually end up using a default constructor" - What about, say, today? – Jirka Hanika Sep 17 '12 at 14:27
  • @JirkaHanika: I've written no code today, so that's easy - 0. – Jon Skeet Sep 17 '12 at 14:40
  • @JonSkeet - Hm, I have a long way to go to accomplish 0. I just looked at some amount of my code (C#, C++, Java). The non-static non-abstract examples typical have quite variable "setup needs", delayed checking of invariants, and are either constructed by reflection or heavily defaultable. Plug-ins, typically. (Older code or generated code also sports lots of DTOs and other C-style structs (with no methods). In one C++89 example it seems to be related to then-limitations of array initialization where I had obviously wanted a non-default constructor and couldn't have it.) – Jirka Hanika Sep 17 '12 at 16:49
20

Edit. Actually, while what I say in my first answer is valid, this is the real reason.:

In the beginning there was C. C is not object-oriented (you can take an OO approach, but it doesn't help you or enforce anything).

Then there was C With Classes, that was later renamed C++. C++ is object-oriented, and therefore encourages encapsulation, and ensuring an object's invariant - upon construction and at the beginning and end of any method, the object is in a valid state.

The natural thing to do with this, is to enforce that a class must always have a constructor to ensure it starts in a valid state - if the constructor doesn't have to do anything to ensure this, then the empty constructor will document this fact.

But a goal with C++ was to be compatible with C to the point that as much as possible, all valid C programs were also valid C++ programs (no longer as active a goal, and the evolution of C separate to C++ means it no longer holds).

One effect of this was the duplication in functionality between struct and class. The former doing things the C way (everything public by default) and the latter doing things in a good OO way (everything private by default, developer actively makes public what they want public).

Another is that in order for a C struct, which couldn't have a constructor because C doesn't have constructors, to be valid in C++, then there had to be a meaning for this to the C++ way of looking at it. And so, while not having a constructor would go against the OO practice of actively ensuring an invariant, C++ took this to mean that there was a default parameterless constructor that acted like it had an empty body.

All C structs were now valid C++ structs, (which meant they were the same as C++ classes with everything - members and inheritance - public) treated from the outside as if it had a single, parameterless constructor.

If however you did put a constructor in a class or struct, then you were doing things the C++/OO way rather than the C way, and there was no need for a default constructor.

Since it served as a shorthand, people kept using it even when compatibility wasn't possible otherwise (it used other C++ features not in C).

Hence when Java came along (based on C++ in many ways) and later C# (based on C++ and Java in different ways), they kept this approach as something coders may already be used to.

Stroustrup writes about this in his The C++ Programming Language and even more so, with more focus upon the "whys" of the language in The Design and Evolution of C++.

=== Original Answer ===

Let's say this didn't happen.

Let's say I don't want a parameterless constructor, because I can't put my class into a meaningful state without one. Indeed, this is something that can happen with struct in C# (but if you can't make meaningful use of an all-zeros-and-nulls struct in C# you're at best using a non-publicly-visible optimisation, and otherwise have a design flaw in using struct).

To make my class able to protect its invariants, I need a special removeDefaultConstructor keyword. At the very least, I'd need to create a private parameterless constructor to make sure no calling code calls the default.

Which complicates the language some more. Better not to do it.

In all, it's best not to think of adding a constructor as removing the default, better to think of having no constructor at all as syntactic sugar for adding a parameterless constructor that doesn't do anything.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • 1
    And yet again, I see someone feels this is a bad enough answer to vote it down, but couldn't be bothered enlightening me or anyone else. Which might be, you know, useful. – Jon Hanna Aug 07 '12 at 19:12
  • Same on my answer. Well i don't see anything wrong here so +1 from me. – Botz3000 Aug 08 '12 at 07:00
  • @Botz3000 I don't care about the score, but if they've a criticism, I'd rather read it. Still, it did make me think of something to add to the above. – Jon Hanna Aug 08 '12 at 08:03
  • 1
    And again with the down-voting without any explanation. Please, if I'm missing something so obvious that it doesn't require explanation, just assume that I'm stupid and do me the favour of explaining it anyway. – Jon Hanna Aug 27 '12 at 23:54
  • +1 I am not an expert, but looking at this from an historical point of view makes the most sense to me. – jogojapan Aug 30 '12 at 06:18
  • 1
    @jogojapan I'm not expert either, but the guy who is - in being the guy who made the decision - wrote about it, so I don't have to be. Incidentally, it's a very interesting book; little on low-level tech and lots on design decisions, with amusing bits like one person's speech saying you should have to donate a kidney before proposing a new feature (you'd think very hard, and only do it twice) right before his speech introducing both templates, and exceptions. – Jon Hanna Aug 30 '12 at 08:41
13

The default, parameterless constructor is added if you don't do anything yourself to take control over object creation. Once you've created a single constructor to take control, the compiler "backs off" and let you have the full control.

If it wouldn't be this way, you would need some explicit way of disabling the default constructor if you only want objects to be constructable through a constructor with parameters.

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
  • You actually have that option. Making the parameterless constructor private. – mw_21 Aug 03 '12 at 08:53
  • 5
    That's not the same. Any method of the class, including static methods, could call it. I prefer having it totally unexisting. – Anders Abel Aug 03 '12 at 08:54
3

I think the question should be the other way around: Why don't you need to declare a default constructor if you haven't defined any other constructors?

A constructor is mandatory for non-static classes.
So i think if you haven't defined any constructors, the generated default constructor is just a convenient feature of the C# compiler, also your class wouldn't be valid without a constructor. So nothing wrong with implicitly generating a constructor that does nothing. It certainly looks cleaner than having empty constructors all around.

If you have already defined a constructor, your class is valid, so why should the compiler assume you want a default constructor? What if you don't want one? Implement an attribute to tell the compiler to not generate that default constructor? I don't think that would be a good idea.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
3

It's a convenience function of the compiler. If you define a Constructor with parameters but don't define a parameterless constructor, the possibility that you don't want to allow a parameterless constructor is much higher.

This is the case for many objects that just don't make sense to initialize with an empty constructor.

Otherwise you'd have to declare a private parameterless constructor for each class that you want to restrict.

In my opinion it's not good style to allow a parameterless constructor for a class that needs parameters to function.

mw_21
  • 150
  • 5
1

The default constructor can be constructed only when the class doesn't have a constructor. Compilers are written in such a way as to provide this only as a backup mechanism.

If you have a parameterized constructor, you may not want an object to be created using the default constructor. Had the compiler provided a default constructor, you would have had to write a no-arg constructor and make it private in order to prevent objects being created using no arguments.

Also, there would be higher chances of you forgetting disabling, or 'privatising' the default constructor, and thereby causing a potential functional error hard to catch.

And now you have to explicitly define a no-arg constructor if you'd like an object to be created either the default way or by passing parameters. This is strongly checked, and the compiler complains otherwise, thereby ensuring no loophole here.

ashes
  • 631
  • 1
  • 6
  • 9
1

Premise

This behaviour can be seen as a natural extension of the decision for classes to have a default public parameterless constructor. Based on the question that's been asked we take this decision as a premise and assume that we are not questioning it in this instance.

Ways to Remove Default Constructor

It follows that there must be a way to remove the default public parameterless constructor. This removal could be accomplished in the following ways:

  1. Declare a non-public parameterless constructor
  2. Automatically remove the parameterless constructor when a constructor with parameters is declared
  3. Some keyword / attribute to indicate to the compiler to remove the parameterless constructor (awkward enough that it is easy to rule out)

Selecting the Best Solution

Now we ask ourselves: If there is no parameterless constructor, what must it be replaced by? and Under what types of scenarios would we want to remove the default public parameterless constructor?

Things start to fall in place. Firstly, it must either be replaced with a constructor with parameters, or with a non-public constructor. Secondly, the scenarios under which you do not want a parameterless constructor are:

  1. We do not want the class to be instantiated at all, or we want to control the visibility of the constructor: declare a non-public constructor
  2. We want to force parameters to be provided on construction: declare a constructor with parameters

Conclusion

There we have it -- exactly the two ways that C#, C++ and Java allow the removal of the default public parameterless constructor.

Zaid Masud
  • 13,225
  • 9
  • 67
  • 88
  • Clearly structured and easy to follow, +1. But regarding (3.) above: I don't think a special keyword for constructor removal is such an awkward idea, and in fact C++11 has introduced `= delete` for this purpose. – jogojapan Aug 30 '12 at 06:16
1

I think this is handled by the compiler. If you open the .net assembly in ILDASM you will see the default constructor, even if it is not in the code. If you define a parameterized constructor the default constructor will not bee seen.

Actually when you define the class (non static), the compiler provides this feature thinking that you will be just creating an instance. And if you want any specific operation to perform you surely will be having your own constructor.

Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
0

Its because when you do not define a constructor the compiler automatically generates a constructor for you which does not take any arguments. When you want something more out of a constructor, you over-ride it. This is NOT function overloading. So the only constructor that the compiler sees now is your constructor which takes an argument. To counter this problem you can pass a default value if the constructor is passed with no value.

Vivek Pradhan
  • 4,777
  • 3
  • 26
  • 46
0

A class need a constructor. It is mandatory requirement.

  • If you don't create one, parameterless constructor will be given to you automatically.
  • If you don't want a parameterless constructor, then you need to create your own.
  • If you need both, parameterless constructor and parameter based-constructor you can add them manually.

I will answer you question with another, why do we want always a default parameterless constructor? there are case where this is not desired, so the developer has the control to add or remove it as is need.

Jaider
  • 14,268
  • 5
  • 75
  • 82