
- i Scott Meyers wrote:
Brian Allison wrote:
As for the advice of the designers of an particular API.... it sounds to me as if your description of their API indicates that you don't consider their API very highly. It sounds (again, from your description) to be hard to use, easy to user to create a bunch of badly working objects, and hard to debug. I do hope that you've got an alternative to that kind of suffering. Or perhaps I misread your description?
I find my intuitions and preferences in tension with advice from others who I believe are worth listening to. This suggests that my intuitions and preferences need refining or that I've misunderstood or misevaluated the advice I find in tension.
Or that the belief you hold about them being worth listening to is not, in fact, properly applied when considering good C++ library design from the user's pouint of view. Remember: you posted this to Boost-users, putting the question of "how important is..." into the context of the users of a library. If I were using a library and I were so easily able to create broken objects, then the first issue I would address is whether or not the library was well-designed. It wouldn't matter how much I liked the guys who wrote the library.
I'm suspicious of a design for a EventLog that seems to require a stream to be useful, yet still allows a EventLog to be created without one, but this seems to be contrary to the advice of a book on how to design an application framework from the people who are responsible for designing one of the most used APIs in existence (.NET). I respect the people in that position, and for those who care about Amazon ratings, it's been well received there (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756/sr=8-1/qid=1158206783/ref=pd_bbs_1/104-6620534-4167149?ie=UTF8&s=books).
Proof by popularity? [The #1 book since Gutenberg has always been The Bible.]
I'll note that C++ itself allows "uninitialized" objects with constructors to be created all the time:
std::ofstream ofs; std::vector<int>::iterator i; std::string s;
Uninitialized objects? The first two are examples of things which don't represent invariants but are interfaces to something else - rarely is it that an interface layer should be used in isolation. [I go a step further and disbelieve that one should ever be *created* in isolation.] The last example is a fine object to create. But we weren't talking about uninitialized objects, we were talking about partial construction, which is a different matter. While the first two are not useable in a default state, they're not meant to ever be created in a *partially constructed* state. Either they're placeholders that are empty and useless, or they're fully assigned and useable.
In each case, there are a few operations that can legitimately be performed on such objects, but many operations lead to UB. Is this fundamentally different from the EventLog example? For example, replace EventLog in my example with ofstream, and you have
std::ofstream ofs; ofs << "Hello World";
Trouble ensues, just as it did in the EventLog example.
Each operation which is valid for the ofstream and iterator is... assignment? I note that neither of them has a partial constructor - which is still the core of the original question, yes? Or perhaps I misread your original poll question? I thought it was about partial construction, not about objects which have an unuseable default state. If instead it was "how do you feel about objects which have an unuseable default state?", then I change my answer to a shrug. After all, I don't use char* unless I have assigned it, and if I can't put off its declaration and can't assign it then I assign to 0. But that's not the same as the antipattern of partial construction. My opinions, as ever, may be ignored at your leisure. They usually are. :) However, they were given in response to your question and not offered out of the blue. regards, Brian