Best practices for abstract factory construction that fails - c++

Background
Suppose we have an implementation of the abstract factory which is invoked as follows:
std::string ObjectName = "An Object Name";
std::string Args = "Argument passed directly to constructor by the factory";
std::unique_ptr<MyBaseClass> MyPtr(ObjectFactory::Instance().Construct(ObjectName,Args));
The factory uses a std::map to turn "An Object Name" into a constructor, which itself takes a std::string as an argument. The idea is that the user knows more about the constructed objects than I do, so I should get out of the way and let the user pass any information they want to the constructor.
Question
This works fine when Args is in exactly the form expected but I don't know the most idiomatic way of handling duff inputs. What should happen if a user supplies an invalid argument string?
I can think of the following:
have the object's constructor throw an exception
require the object provides a bool Validate(std::string x) method, which checks whether x is a valid argument string
Have the factory use the default constructor, and then call an initialisation method afterwards (begs the question: what if the init method fails?)
Set a bool member variable which, if true, means "this object is not in a sane state"
Some other option I've not thought of

Throw an exception. You're constructing an object (albeit in a different way than just new), failure is an exception that needs to be handled if it can happen.
"Solution 2" has nothing to do with handling this issue, it's more of a how to determine bad input. For such it can be an acceptable solution, but again it has nothing to do with the question at hand.
Solution 3 leaves the object in an indeterminate state in case of failure, which is unacceptable.
Solution 4 is another way to do it, and the only way if you don't have exception support in your language, but we do. Exceptions in this case are strictly better in my opinion because failing to construct an object is an action so destructive it should require alternative code or the program to die.

The first solution is the standard solution for constructor failure.
Solution #2 and #4 are pretty error prone (user might forget to check)
Solution #3 doesn't solve the problem
If you're making a library or just writing code that might be re-used in a "no exceptions allowed" environment, you could consider returning std::unique_ptr{nullptr}. Even if it is also error prone, that's the other standard way of handling construction failure.

Maybe the easiest way is to return a nullptr.

What ever you do, do not throw an exception from a constructor (as per Item #10 in More effective C++), as the destructor will not be called. It leads to newbie memory leaks and forces users to worry about exception handling.
I would just assert and return a Null Object, with dummy factory method implementations, or return nullptr.

Related

Resource handles - prohibiting default constructors?

So, I've been doing some library development and came to a dilemma. Library is private, so I can't share it, but I feel this could be a meaningful question.
The dilemma presented itself as an issue over why there is no default constructor for a resource handling class in the library. The class handles a specific file structure, which is not really important, but lets call the class Quake3File.
The request was then to implement a default constructor and the "appropriate" Open/Close methods. My line of thinking is RAII style, that is if you create a instantiation of the class you must give it a resource that it handles. Doing this ensures that any and all successfully constructed handles are valid and IMO eliminates a whole class of bugs.
My suggestion was to keep a (smart)pointer around and then instead of having to implement a Open/Close and open a can of worms, the user creates the class on the free store to "Open" it and deletes is when you want to "Close" it. Using a smart pointer will even "Close" it for you when it gets out of scope.
This is where the conflict comes in, I like to mimic the STL design of classes, since that makes my classes easier to use. Since I'm making a class that essentially deals with files and if I take std::fstream as a guide, then I am not sure if I should implement a default constructor. The fact that the entire std::fstream hierarchy does it points me to a Yes, but my own thinking goes to No.
So the questions are more or less:
Should resource handles really have default constructors?
What is a good way implement a default constructor on a class that deals with files? Just set the internal state to an invalid one and if a user missuses it by not giving it a resource have it result in undefined behavior? Seems strange to want to take it down this route.
Why does the STL implement the fstream hierarchy with default constructors? Legacy reasons?
Hope my question is understood. Thanks.
One could say that there are two categories of RAII classes: "always valid" and "maybe empty" classes. Most classes in standard libraries (or near-standard libraries like Boost) are of the latter category, for a couple of reasons that I'll explain here. By "always valid", I mean classes that must be constructed into a valid state, and then remain valid until destruction. And by "maybe empty", I mean classes that could be constructed in an invalid (or empty) state, or become invalid (or empty) at some point. In both cases, the RAII principles remain, i.e., the class handles the resource and implements an automatic management of it, as in, it releases the resource upon destruction. So, from a user's perspective, they both enjoy the same protections against leaking resources. But there are some key differences.
First thing to consider is that one key aspect of almost any resource that I can think of is that resource acquisition can always fail. For example, you could fail to open a file, fail to allocate memory, fail to establish a connection, fail to create a context for the resource, etc.. So, you need a method to handle this potential failure. In an "always valid" RAII class, you have no choice but to report that failure by throwing an exception from the constructor. In a "maybe empty" class, you can choose to report that failure either through leaving the object in an empty state, or you can throw an exception. This is probably one of the main reasons why the IO-streams library uses that pattern, because they decided to make exception-throwing an optional feature in its classes (probably because of many people's reticence to using exceptions too much).
Second thing to consider is that "always valid" classes cannot be movable classes. Moving a resource from one object to another implies making the source object "empty". This means that an "always valid" class will have to be non-copyable and non-movable, which could be a bit of an annoyance for the users, and could also limit your own ability to provide an easy-to-use interface (e.g., factory functions, etc.). This will also require the user to allocate the object on freestore whenever he needs to move the object around.
(EDIT)
As pointed out by DyP below, you could have an "always valid" class that is movable, as long as you can put the object in a destructible state. In other words, any other subsequent use of the object would be UB, only destruction will be well-behaved. It remains, however, that a class that enforces an "always valid" resource will be less flexible and cause some annoyance for the user.
(END EDIT)
Obviously, as you pointed out, an "always valid" class will be, in general, more fool-proof in its implementation because you don't need to consider the case where the resource is empty. In other words, when you implement a "maybe empty" class you have to check, within each member function, if the resource is valid (e.g., if the file is open). But remember that "ease of implementation" is not a valid reason to dictate a particular choice of interface, the interface faces the user. But, this problem is also true for code on the user's side. When the user deals with a "maybe empty" object, he always has to check validity, and that can become troublesome and error-prone.
On the other hand, an "always valid" class will have to rely solely on exception mechanisms to report its errors (i.e., error conditions don't disappear because of the postulate of "always valid"), and thus can present some interesting challenges in its implementation. In general, you will have to have strong exception safety guarantees for all your functions involving that class, including both implementation code and user-side code. For example, if you postulate that the object is "always valid", and you attempt an operation that fails (like reading beyond the end of a file), then you need to roll back that operation and bring the object back to its original valid state, to enforce your "always valid" postulate. The user will, in general, be forced to do the same when relevant. This may or may not be compatible with the kind of resource you are dealing with.
(EDIT)
As pointed out by DyP below, there are shades of grey between those two types of RAII classes. So, please note that this explanation is describing two pole-opposites or two general classifications. I am not saying that this is a black-and-white distinction. Obviously, many resources have varying degrees of "validity" (e.g., an invalid file-handler could be in a "not opened" state or a "reached end-of-file" state, which could be handled differently, i.e., like a "always opened", "maybe at EOF", file-handler class).
(END EDIT)
Should resource handles really have default constructors?
Default constructors for RAII classes are generally understood as creating the object into an "empty" state, meaning that they are only valid for "maybe empty" implementations.
What is a good way implement a default constructor on a class that deals with files? Just set the internal state to an invalid one and if a user missuses it by not giving it a resource have it result in undefined behavior? Seems strange to want to take it down this route.
Most resources that I have ever encountered have a natural way to express "emptiness" or "invalidity", whether it be a null pointer, null file-handle, or just a flag to mark the state as being valid or not. So, that's easy. However, this does not mean that a misuse of the class should trigger "undefined behavior". It would be absolutely terrible to design a class like that. As I said earlier, there are error conditions that can occur, and making the class "always valid" does not change that fact, only the means by which you deal with them. In both cases, you must check for error conditions and report them, and fully specify the behavior of your class in case they happen. You cannot just say "if something goes wrong, the code has 'undefined behavior'", you must specify the behavior of your class (one way or another) in case of error conditions, period.
Why does the STL implement the fstream hierarchy with default constructors? Legacy reasons?
First, the IO-stream library is not part of the STL (Standard Template Library), but that's a common mistake. Anyway, if you read my explanations above you will probably understand why the IO-stream library chose to do things the way it does. I think that it essentially boils down to avoiding exceptions as a required, fundamental mechanism for their implementations. They allow exceptions as an option, but don't make them mandatory, and I think that must have been a requirement for many people, especially back in the days it was written, and probably still today.
I think that each case should be considered separately, but for a file class I'd certainly consider the introduction of an "invalid state" like "file cannot be opened" (or "no file attached to the wrapper handler class").
For example, if you don't have this "invalid file" state, you will force a file loading method or function to throw exceptions for the case that a file cannot be opened. I don't like that, because the caller then should use lots of try/catch wrappers around file loading code, while instead a good-old boolean check would be just fine.
// *** I don't like this: ***
try
{
File f1 = loadFile("foo1");
}
catch(FileException& e)
{
...handle load failure, e.g. use some defaults for f1
}
doSomething();
try
{
File f2 = loadFile("foo2");
}
catch(FileException& e)
{
...handle load failure for f2
}
I prefer this style:
File f1 = loadFile("foo");
if (! f1.valid())
... handle load failure, e.g. use some default settings for f1...
doSomething();
File f2 = loadFile("foo2");
if (! f2.valid())
... handle load failure
Moreover, it may also make sense to make the File class movable (so you may also put File instances in containers, e.g. have a std::vector<File>), and in this case you must have an "invalid" state for a moved-from file instance.
So, for a File class, I'd consider the introduction of an invalid state to be just fine.
I also wrote a RAII template wrapper to raw resources, and I implemented an invalid state there as well. Again, this makes it possible to properly implement move semantics, too.
At least IMO, your thinking on this subject is probably better than that shown in iostreams. Personally, if I were creating an analog of iostreams from scratch today, it probably would not have a default ctor and separate open. When I use an fstream, I nearly always pass the file name to the ctor rather than default-constructing followed by using open.
Nearly the only point in favor of having a default ctor for a class like this is that it makes putting them into a collection easier. With move semantics and the ability to emplace objects, that becomes much less compelling though. It was never truly necessary, and is now almost irrelevant.

Should I throw an exception

I am C# programmer but now I want to get more into C++.
I know the basics of C++ but I don't know how to handle errors.
For example: I am writing a library. I create an constructor which requests an integer as an argument.
If that integer is bigger than 50, it is an error.
In C# I would throw an ArgumentOutOfRange exception, but what should I do in C++?
In C# I would throw an ArgumentOutOfRange exception but what should I do in c++?
First you should consider if that should not be a precondition of your function, leaving the responsibility of checking whether the value is in range to the caller.
If you decide for this option, then invoking the function with an out-of-range value would be undefined behavior, and inside the function you could just have a debug assertion to help you spot possible misuses - without the need of throwing any exception.
If you decide that the function should have a wide contract, on the other hand, and react in a well-defined way by throwing an exception when the argument is outside the permitted range, then you could throw an std::out_of_range exception.
For example: I am writing a libary [...]
If you are writing a library, meaning that you do not know the exact requirements of your clients in terms of performance and robustness, you may consider providing two such functions - one with a wide contract that throws exceptions, and one with a narrow contract that assumes the client provides meaningful input.
This way, the user of your library could decide based on their use cases whether or not it is OK to pay for the overhead of checking the correctness of the input each time your function is called.
This is, for instance, the strategy adopted by the C++ Standard Library for std::vector, which provides a non-throwing operator[] with a narrow contract for accessing elements of the collection based on the index (this function has undefined behavior if the index is out-of-bounds), and a member function at() that performs index checking and throws an exception if the index is out-of-bounds.
It depends on whether an integer larger than 50 could possibly be passed to the constructor as part of normal program flow, or whether that's an exceptional condition. But in general the only way to have object construction fail is by throwing an exception.
Your user code might look like this:
int n = parse_user_input()
if (n < 50)
{
Foo x(n);
x.do_cool_stuff();
}
else
{
// report user error
}
That is, you don't actually use exceptions for normal control flow. With that sort of code pattern, it would be perfectly fine for Foo::Foo(int) to throw an exception if the argument were out of range.
You can find useful standard exception classes in <stdexcept>.
The same thing as in C#: throw an exception. This is the only way to prevent an object from being constructed.
std::invalid_argument is a good standard choice regarding what to throw.
From the C++ FAQ: [17.8] How can I handle a constructor that fails?
Excerpt:
Throw an exception.
Constructors don't have a return type, so it's not possible to use
return codes. The best way to signal constructor failure is therefore
to throw an exception. If you don't have the option of using
exceptions, the "least bad" work-around is to put the object into a
"zombie" state by setting an internal status bit so the object acts
sort of like it's dead even though it is technically still alive.
So, throwing std::invalid_argument or std::out_of_range would be perfectly acceptable for your situation. You could also throw a custom exception if that would be beneficial in your situation. In the C++ FAQ see: [17.12] What should I throw?

When to use boost::optional and when to use std::unique_ptr in cases when you want to implement a function that can return "nothing"?

From what I understand there are 2* ways you can implement a function that sometimes doesnt return a result(for example is person found in a list of ppl).
*- we ignore raw ptr version, pair with a bool flag, and exception when none found version.
boost::optional<Person> findPersonInList();
or
std::unique_ptr<Person> findPersonInList();
So are there any reasons to prefere one over the other?
It depends: do you wish to return a handle or a copy.
If you wish to return a handle:
Person*
boost::optional<Person&>
are both acceptable choices. I tend to use a Ptr<Person> class which throws in case of null access, but that's my paranoia.
If you wish to return a copy:
boost::optional<Person> for non polymorphic classes
std::unique_ptr<Person> for polymorphic classes
because dynamic allocation incurs an overhead, so you only use it when necessary.
The general answer is that your intentions are expressed by boost::optional and not by std::unique_ptr. That said, your special case of a find operation should probably conform to the standard library way of doing it, assuming that your underlying type has a concept of iterators: return an iterator to end() if no element is found, and an iterator to the element otherwise.
boost::optional more clearly states your intention. You need to document explicitly that empty std::unique_ptr means there's no value to return
There is a fourth way of doing it : make the function throw an exception if there is nothing found.
I know this does not really answer your question and therefore I apologize but maybe you hadn't thought about it.
Ah, Xeo didn't show up yet?
Well, I told you this once, and I'll tell it again: these two are completely different objects with different purposes.
unique_ptr means I own an object. It's just different way of saying "I am an object". Thus, null unique_ptr is something that can attract attention. I was expecting an object, but I got nothing; the code must be wrong!
optional means I can sometimes be not initialized, but that's ok. In this case, there's no worries; if it's None, it's the behavior that has been thought of.
The fact that both implicitly convert to bool doesn't mean they can be used interchargeably. Use optional with code that is likely not to produce any output (reading a stream, for example). Use unique_ptr in factory objects; they will most likely create an object for you, and if not, throw an exception.
A conclusion regarding your example : find should return optional.
Conceptually boils down to this, given the nullable requirement:
std::optional has value semantics, stack store.
std::unique_ptr has move semantics, heap store.
If you want value semantics and heap store, use std::indirect http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0201r1.pdf .
(If you want move semantics and stack store... I don't know. I guess it is a unique_ptr with a stack allocator?)
So are there any reasons to prefere one over the other?
They express very different intent: optional says that the function may not give a result to give you (and that is not an error case). unique_ptr tells you something about ownership semantics (and is more acceptable to use with null, to express an error).
Usually I would use the one that expresses best the intent behind the interface.
For example, consider that you were writing a HTTP server, that attempts to parse a received buffer into a HTTP request object. When you attempt to parse an incomplete buffer, there is no error case, you simply have to wait and buffer more data, then try again.
I would express this using optional,to make it clear that the function may not return anything (and not returning anything is not an error case).
In case my parsing had to validate stuff (e.g. a regex parser should yield an error if the parsed expression is invalid regex) I would return a null unique_ptr, or better yet, throw an exception.

Is it abusive to implement the "execute-around" idiom with scoped objects?

Should scoped objects (with complimentary logic implemented in constructor and destructor) only be used for resource cleanup (RAII)?
Or can I use it to implement certain aspects of the application's logic?
A while ago I asked about Function hooking in C++. It turns out that Bjarne addressed this problem and the solution he proposes is to create a proxy object that implements operator-> and allocates a scoped object there. The "before" and "after" are implemented in the scoped object's constructor and destructor respectively.
The problem is that destructors should not throw. So you have to wrap the destructor in a try { /* ... */ } catch(...) { /*empty*/ } block. This severely limits the ability to handle errors in the "after" code.
Should scoped objects only be used to cleanup resources or can I use it for more than that? Where do I draw the line?
If you pedantically consider the definition of RAII, anything you do using scoping rules and destructor invocation that doesn't involve resource deallocation simply isn't RAII.
But, who cares? Maybe what you're really trying to ask is,
I want X to happen every time I leave function Y. Is it
abusive to use the same scoping rules and destructor invocation that
RAII uses in C++ if X isn't resource deallocation?
I say, no. Scratch that, I say heck no. In fact, from a code clarity point of view, it might be better to use destructor calls to execute a block of code if you have multiple return points or possibly exceptions. I would document the fact that your object is doing something non-obvious on destruction, but this can be a simple comment at the point of instantiation.
Where do you draw the line? I think the KISS principle can guide you here. You could probably write your entire program in the body of a destructor, but that would be abusive. Your Spidey Sense will tell you that is a Bad Idea, anyway. Keep your code as simple as possible, but not simpler. If the most natural way to express certain functionality is in the body of a destructor, then express it in the body of a destructor.
You want a scenario where, guaranteed, the suffix is always done. That sounds exactly like the job of RAII to me. I however would not necessarily actually write it that way. I'd rather use a method chain of templated member functions.
I think with C++11 you can semi-safely allow the suffix() call to throw. The strict rule isn't "never throw from a destructor", although that's good advice, instead the rule is:
never throw an exception from a destructor while processing another
exception
In the destructor you can now use std::current_exception, which I think verifies the "while processing another exception" element of the destructor+exception rule. With this you could do:
~Call_proxy() {
if (std::current_exception()) {
try {
suffix();
}
catch(...) {
// Not good, but not fatal perhaps?
// Just don't rethrow and you're ok
}
}
else {
suffix();
}
}
I'm not sure if that's actually a good idea in practise though, you have a hard problem to deal with if it throws during the throwing of another exception still.
As for the "is it abuse" I don't think it's abusive anymore than metaprogramming or writing a?b:c instead of a full blown if statement if it's the right tool for the job! It's not subverting any language rules, simply exploiting them, within the letter of the law. The real issue is the predictability of the behaviour to readers unfamiliar with the code and the long term maintainability, but that's an issue for all designs.

Terminate object creation in constructor [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to handle failure in constructor in C++?
Is there any pattern in C++ so i could terminate object creation in constructor if something fails? And so client that invoke constructor got information about failed obj creation?
Yes, you can: throw an exception. This is pretty much the only sensible way. By choosing the appropriate exception class (either standard or your own) and supplying a good error message etc you'll be able to tell the caller what's gone wrong.
The FAQ has more details.
You need to throw an exception. That is the best way to handle failing object creation.
Constructor Failures should be an Interesting read from Herb Sutter's GOTW.
Another way of doing this is that if a constructor encounters an error, set a status bit and let the user call IsOK() to see if construction actually worked.
But this is considered Obsolete.
Herb Says:
I have found the "if a constructor encounters an error, set a status bit and let the user call IsOK() to see if construction actually worked" method to be outdated, dangerous, tedious, and in no way better than throwing an exception.
Throwing an exception is the usual way to handle that, however, i discourage you from the pattern of throwing exceptions in constructors.
We cannot ensure that a constructor will not throw an exception but it seems to me an anti-pattern to rely on exceptions thrown by constructors.
There is a subtle difference :)
I usually prefer to deal with constructors that should not fail, and move the sensible logic that can fail in an Initialize method that can return a value or throw an exception.
It is more clean and avoid you bad headache when the code gets more complicated!
This is an example of why I blieve so: http://www.cs.technion.ac.il/~imaman/programs/throwingctor.html
Another interesting post is C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4]
As aix explained, throwing from constructor is the only sensible option.
Alternatively, you can use Named Constructor Idiom (see here and here) and return null pointer if creation of new object ends up with failure.