
On 05/06/2011 04:10 PM, Vladimir Batov wrote:
From: "Jeff Flinn" <TriumphSprint2000@hotmail.com>
has no default. I am not sure if extending the above to
But is an enum IStreamable? Aren't you relying on implicit conversion to/from int for streaming? An int *is* default constructable.
You are correct. The example I gave in a haste is probably more confusing than helping. A better (and real) example of objectified enum -- the direction class -- is in the 'convert' documentation.
Just as another data point, looking at *our* classes, I see many more types that are not IStreamable, but are default-constructable. In looking at my own types, those that are not default-constructable would not make sense to be IStreamable. The types I find that are non-default-constructable tend to hold references to items passed as a ctor args.
I am not sure what to say. I guess, our domains, programming styles, etc. differ. Does it mean that one needs to be better supported than the other or another?
Still, I have a suspicion (and that's just that -- a suspicion) that many default-constructors can be reasonably questioned. Even a such a simlpe "class" as int default-constructed to 0. I am tempted to ask 'why 0?' why not MAX_INT or '-1'. My point is that an object needs to be constructed explicitly with the valu it needs to be assigned to, i.e.
int v(0);
that is for readability, maintainability, etc. Yes, built-in type do have default constructors. However, it was not a design choice but rather the practical necessity to be able to incorporate built-in types into C++ framework. However, that technical "hack" to a legacy-support-related issue as been misunderstood and carried over to proper classes. That's my view of course and as any view it can be wrong.
The fact that built-in types in C++ have a special "uninitialized" state separate from the default constructed state necessary makes them a special case. Nonetheless, a default constructor is often useful even if it serves to create an arbitrary initial state with only the guarantee that it won't leak memory, etc. Basically it allows the type to serve as its own optional<>, with the caveat that you cannot check if it has been initialized and don't need to dereference it explicitly. This often is more convenient/leads to better syntax that having to use optional<> or a smart pointer of some type everywhere. For instance, arrays (and some other containers) require a default constructor. Also, if the type is a member of some other class, it may be convenient to be able to initialize it in the constructor body or elsewhere, as constructing it using the initializer list may be too limiting or inconvenient.