I want to open a file in a class constructor. It is possible that the opening could fail, then the object construction could not be completed. How to handle this failure? Throw exception out? If this is possible, how to handle it in a non-throw constructor?
-
Possible duplicate of [What's the best technique for exiting from a constructor on an error condition in C++](https://stackoverflow.com/questions/737653/whats-the-best-technique-for-exiting-from-a-constructor-on-an-error-condition-i) – ks1322 Feb 13 '18 at 14:24
-
1"If you can’t use a recoverable error handling mechanism without exceptions in a constructor, then don’t use a constructor." Read more here: https://foonathan.net/2017/01/exceptions-constructor/. – Gabriel Staples Dec 13 '19 at 04:07
8 Answers
If an object construction fails, throw an exception.
The alternative is awful. You would have to create a flag if the construction succeeded, and check it in every method.

- 62,405
- 41
- 173
- 273
-
7It would be great to actually propose a "real" solution too, such as passing a `istream&` parameter :) – Matthieu M. Feb 14 '11 at 08:03
-
@Matthie Yes, the inversion of control. I keep forgetting about it. Thanks for the reminder. – BЈовић Feb 14 '11 at 08:15
-
Nah nah it is not awful w/o exceptions: http://llvm.org/docs/ProgrammersManual.html#fallible-constructors – Nils Jul 20 '17 at 11:18
-
2@Nils That would be called an abomination in any normal code review. Plus you have to check if the object is in a normal state, before do something with it. – BЈовић Jul 20 '17 at 12:02
I want to open a file in a class constructor. It is possible that the opening could fail, then the object construction could not be completed. How to handle this failure? Throw exception out?
Yes.
If this is possible, how to handle it in a non-throw constructor?
Your options are:
- redesign the app so it doesn't need constructors to be non-throwing - really, do it if possible
- add a flag and test for successful construction
- you could have each member function that might legitimately be called immediately after the constructor test the flag, ideally throwing if it's set, but otherwise returning an error code
- This is ugly, and difficult to keep right if you have a volatile group of developers working on the code.
- You can get some compile-time checking of this by having the object polymorphically defer to either of two implementations: a successfully constructed one and an always-error version, but that introduces heap usage and performance costs.
- You can move the burden of checking the flag from the called code to the callee by documenting a requirement that they call some "is_valid()" or similar function before using the object: again error prone and ugly, but even more distributed, unenforcable and out of control.
- You can make this a little easier and more localised for the caller if you support something like:
if (X x) ...
(i.e. the object can be evaluated in a boolean context, normally by providingoperator bool() const
or similar integral conversion), but then you don't havex
in scope to query for details of the error. This may be familiar from e.g.if (std::ifstream f(filename)) { ... } else ...;
- You can make this a little easier and more localised for the caller if you support something like:
- you could have each member function that might legitimately be called immediately after the constructor test the flag, ideally throwing if it's set, but otherwise returning an error code
- have the caller provide a stream they're responsible for having opened... (known as Dependency Injection or DI)... in some cases, this doesn't work that well:
- you can still have errors when you go to use the stream inside your constructor, what then?
- the file itself might be an implementation detail that should be private to your class rather than exposed to the caller: what if you want to remove that requirement later? For example: you might have been reading a lookup table of precalculated results from a file, but have made your calculations so fast there's no need to precalculate - it's painful (sometimes even impractical in an enterprise environment) to remove the file at every point of client usage, and forces a lot more recompilation rather than potentially simply relinking.
- force the caller to provide a buffer to a success/failure/error-condition variable which the constructor sets: e.g.
bool worked; X x(&worked); if (worked) ...
- this burden and verbosity draws attention and hopefully makes the caller much more conscious of the need to consult the variable after constructing the object
- force the caller to construct the object via some other function that can use return codes and/or exceptions:
if (X* p = x_factory()) ...
- Smart_Ptr_Throws_On_Null_Deref p_x = x_factory();
</li> <li>
X x; // never usable; if (init_x(&x)) ...` - etc...
In short, C++ is designed to provide elegant solutions to these sorts of issues: in this case exceptions. If you artificially restrict yourself from using them, then don't expect there to be something else that does half as good a job.
(P.S. I like passing variables that will be modified by pointer - as per worked
above - I know the FAQ lite discourages it but disagree with the reasoning. Not particularly interested in discussion thereon unless you've something not covered by the FAQ.)

- 102,968
- 15
- 177
- 252
New C++ standard redefines this in so many ways that it's time to revisit this question.
Best choices:
Named optional: Have a minimal private constructor and a named constructor:
static std::experimental::optional<T> construct(...)
. The latter tries to set up member fields, ensures invariant and only calls the private constructor if it'll surely succeed. Private constructor only populates member fields. It's easy to test the optional and it's inexpensive (even the copy can be spared in a good implementation).Functional style: The good news is, (non-named) constructors are never virtual. Therefore, you can replace them with a static template member function that, apart from the constructor parameters, takes two (or more) lambdas: one if it was successful, one if it failed. The 'real' constructor is still private and cannot fail. This might sound an overkill, but lambdas are optimized wonderfully by compilers. You might even spare the
if
of the optional this way.
Good choices:
Exception: If all else fails, use an exception - but note that you can't catch an exception during static initialization. A possible workaround is to have a function's return value initialize the object in this case.
Builder class: If construction is complicated, have a class that does validation and possibly some preprocessing to the point that the operation cannot fail. Let it have a way to return status (yep, error function). I'd personally make it stack-only, so people won't pass it around; then let it have a
.build()
method that constructs the other class. If builder is friend, constructor can be private. It might even take something only builder can construct so that it's documented that this constructor is only to be called by builder.
Bad choices: (but seen many times)
Flag: Don't mess up your class invariant by having an 'invalid' state. This is exactly why we have
optional<>
. Think ofoptional<T>
that can be invalid,T
that can't. A (member or global) function that works only on valid objects works onT
. One that surely returns valid works onT
. One that might return an invalid object returnoptional<T>
. One that might invalidate an object take non-constoptional<T>&
oroptional<T>*
. This way, you won't need to check in each and every function that your object is valid (and thoseif
s might become a bit expensive), but then don't fail at the constructor, either.Default construct and setters: This is basically the same as Flag, only that this time you're forced to have a mutable pattern. Forget setters, they unnecessarily complicate your class invariant. Remember to keep your class simple, not construction simple.
Default construct and
init()
that takes a ctor parameters: This is nothing better than a function that returns anoptional<>
, but requires two constructions and messes up your invariant.Take
bool& succeed
: This was what we were doing beforeoptional<>
. The reasonoptional<>
is superior, you cannot mistakenly (or carelessly!) ignore thesucceed
flag and continue using the partially constructed object.Factory that returns a pointer: This is less general as it forces the object to be dynamically allocated. Either you return a given type of managed pointer (and therefore restrict allocation/scoping schema) or return naked ptr and risk clients leaking. Also, with move schematics performance-wise this might become less desirable (locals, when kept on stack, are very fast and cache-friendly).
Example:
#include <iostream>
#include <experimental/optional>
#include <cmath>
class C
{
public:
friend std::ostream& operator<<(std::ostream& os, const C& c)
{
return os << c.m_d << " " << c.m_sqrtd;
}
static std::experimental::optional<C> construct(const double d)
{
if (d>=0)
return C(d, sqrt(d));
return std::experimental::nullopt;
}
template<typename Success, typename Failed>
static auto if_construct(const double d, Success success, Failed failed = []{})
{
return d>=0? success( C(d, sqrt(d)) ): failed();
}
// this version keeps inputs in alternative path
template<typename Success, typename Alternative>
static auto in_case_constructible(const double d, Success success, Alternative alternative)
{
return d>=0? success( C(d, sqrt(d)) ): alternative(d);
}
/*C(const double d)
: m_d(d), m_sqrtd(d>=0? sqrt(d): throw std::logic_error("C: Negative d"))
{
}*/
private:
C(const double d, const double sqrtd)
: m_d(d), m_sqrtd(sqrtd)
{
}
double m_d;
double m_sqrtd;
};
int main()
{
const double d = 2.0; // -1.0
// method 1. Named optional
if (auto&& COpt = C::construct(d))
{
C& c = *COpt;
std::cout << c << std::endl;
}
else
{
std::cout << "Error in 1." << std::endl;
}
// method 2. Functional style
C::if_construct(d, [&](C c)
{
std::cout << c << std::endl;
},
[]
{
std::cout << "Error in 2." << std::endl;
});
}

- 10,687
- 23
- 36
-
`bool& succeed ` need not actually be a bool. It could also be an error code that would give you more information then a std::optional. – Dan Ganea Feb 18 '19 at 21:02
-
@GaneaDanAndrei: If your type contains either the value or error info, then you'd _return_ it (not take it as an arg). If it contains just the error info, then you might return an `std::variant
` - no need for mutable input either. Go for `boost::variant` if you don't have it in your compiler yet. – lorro Feb 18 '19 at 21:30 -
In method 2, is there an unnecessary copy of C since it's built and passed by value to `success`? If so, what can we do to avoid it? (For example if C is very expensive to build) – Michele Piccolini Nov 10 '21 at 17:39
-
throwing exception is bad idea because there is more chance to make mistake. developers who use your class, needs to know about possible exception. It is not common to wrap all object creations with a try block. Also exception should be used whenever an **exceptional error** might be occurred not "any error". – S.M.Mousavi Mar 31 '22 at 12:59
-
@MichelePiccolini Sorry for the late answer. I expect it to be movable in a practical use. – lorro Jul 31 '22 at 22:26
My suggestion for this specific situation is that if you don't want a constuctor to fail because if can't open a file, then avoid that situation. Pass in an already open file to the constructor if that's what you want, then it can't fail...

- 29,554
- 19
- 87
- 130
-
4And what if the content of the file is empty? Or contains invalid data? – CashCow Feb 14 '11 at 10:37
-
5The poster only said he wanted to open the file in the constructor. Obviously if he's doing more then it could fail in other ways and would need to be dealt with appropriately. – jcoder Feb 14 '11 at 12:45
One way is to throw an exception. Another is to have a 'bool is_open()' or 'bool is_valid()' functuon that returns false if something went wrong in the constructor.
Some comments here say it's wrong to open a file in the constructor. I'll point out that ifstream is part of the C++ standard it has the following constructor:
explicit ifstream ( const char * filename, ios_base::openmode mode = ios_base::in );
It doesn't throw an exception, but it has an is_open function:
bool is_open ( );

- 75,001
- 122
- 434
- 781
-
1Well, `ifstream` is an RAII object which manages the reference to the file. That's quite a different case than most of the "classes that open files in their constructors" (that I've seen anyway) Good C++ code doesn't have explicit `delete` statements either, but it's impossible to implement smart pointers without it. – Billy ONeal Feb 14 '11 at 07:59
-
Just to mention it: a lot of people don't like the is_open() or is_valid() approach and consider it bad. It's because users of the class can easily forget to call this method and you end up having a partially-constructed class and need to include the is_open() test in a lot of member functions. It might be an option, though, in some cases. – sstn Feb 14 '11 at 08:18
I want to open a file in a class constructor.
Almost certainly a bad idea. Very few cases when opening a file during construction is appropriate.
It is possible that the opening could fail, then the object construction could not be completed. How to handle this failure? Throw exception out?
Yep, that'd be the way.
If this is possible, how to handle it in a non-throw constructor?
Make it possible that a fully constructed object of your class can be invalid. This means providing validation routines, using them, etc...ick

- 40,307
- 7
- 73
- 125
-
6Why is opening a file, or any other resource, in a constructor a bad idea? – Jörgen Sigvardsson Feb 14 '11 at 07:51
-
4@Jörgen Sigvardsson: Because it would be better to write your class in terms of any given `istream` or `ostream` object. That way you could do testing replacing the stream with a stringstream. – Billy ONeal Feb 14 '11 at 07:54
-
1@Jorgen Sigvardsson: This goes against the Dependency Injection philosophy. Your question is better read the other way around: why tie your hand in the back ? By explicitly using a `open` in your class, you are preventing any reuse from say memory-mapped file for example ? On the other hand, by using a base-class (stream-like) you can pass in anything that implement its interface; this makes testing and reuse easier. – Matthieu M. Feb 14 '11 at 08:01
-
1@Crazy: so the standard library does it wrong too? `std::fstream` opens the file in its constructor. – jalf Feb 14 '11 at 08:20
-
1@Matthieu: I don't see how the amount of work in constructors has anything to do with DI...? Also, the presence of a "hard working" constructor doesn't preclude providing an open method. – Jörgen Sigvardsson Feb 14 '11 at 08:25
-
1@jalf: I think there is a huge difference between a RAII object, whose purpose is to acquire the resources, and a traditional object which happens to require a particular resource for its construction. They are different beasts, thus different rules apply. – Matthieu M. Feb 14 '11 at 09:15
-
@Jorgen Sigvardsson: I didn't say anything about amount of work. I said that *hard-coding* `std::ifstream` is akin to *hard-coding* `std::cout` for logging. In the words of Henry Ford: *You can have any color as long as it's black*. – Matthieu M. Feb 14 '11 at 09:20
-
Of course you should have well-factored code. It is not necessarily the case that your class will read in the entire stream in one go, as the file may be far too large to store in memory. We don't know after all what the user is going to do with the file here. And a generic stream may not be appropriate if it has to be random-access. We don't even know if the user is opening the file to read, to write or to do both. – CashCow Feb 14 '11 at 10:42
-
@Matthieu: true. I interpreted his answer as applying to *all* classes though. But I agree with your take on it: raii objects should acquire resources in ctor, and other objects should rely on DI of some kind. – jalf Feb 14 '11 at 12:31
-
@jalf - except that a good portion of RAII objects do not acquire resources in the constructor, the resource is passed in. A class specifically built for the purposes of handling a resource is a bit different from some general case though, which is why I said 'almost certainly' and 'very few cases' as qualifiers. The OP didn't give enough information to be sure. – Edward Strange Feb 14 '11 at 17:14
A constructor may well open a file (not necessarily a bad idea) and may throw if the file-open fails, or if the input file does not contain compatible data.
It is reasonable behaviour for a constructor to throw an exception, however you will then be limited as to its use.
You will not be able to create static (compilation unit file-level) instances of this class that are constructed before "main()", as a constructor should only ever be thrown in the regular flow.
This can extend to later "first-time" lazy evaluation, where something is loaded the first time it is required, for example in a boost::once construct the call_once function should never throw.
You may use it in an IOC (Inversion of Control / Dependency Injection) environment. This is why IOC environments are advantageous.
Be certain that if your constructor throws then your destructor will not be called. So anything you initialised in the constructor prior to this point must be contained in an RAII object.
More dangerous by the way can be closing the file in the destructor if this flushes the write buffer. No way at all to handle any error that may occur at this point properly.
You can handle it without an exception by leaving the object in a "failed" state. This is the way you must do it in cases where throwing is not permitted, but of course your code must check for the error.

- 30,981
- 5
- 61
- 92
Use a factory.
A factory can be either an entire factory class "Factory<T>
" for building your "T
" objects (it doesn't have to be a template) or a static public method of "T
". You then make the constructor protected and leave the destructor public. That ensures new classes can still derive from "T
" but no external code other than them can call the constructor directly.
With factory methods (C++17)
class Foo {
protected:
Foo() noexcept; // Default ctor that can't fail
virtual bool Initialize(..); // Parts of ctor that CAN fail
public:
static std::optional<Foo> Create(...) // 'Stack' or value-semantics version (no 'new')
{
Foo out();
if(foo.Initialize(..)) return {out};
return {};
}
static Foo* /*OR smart ptr*/ Create(...) // Heap version.
{
Foo* out = new Foo();
if(foo->Initialize(...) return out;
delete out;
return nullptr;
}
virtual ~Foo() noexcept; // Keep public to allow normal inheritance
};
Unlike setting 'valid' bits or other hacks, this is relatively clean and extensible. Done right it guarantees no invalid objects ever escape into the wild, and writing derived 'Foo's is still straightforward. And since factory functions are normal functions, you can do a lot of other things with them that constructors can't.
In my humble opinion you should never put any code that can realistically fail into a constructor. That pretty much means anything that does I/O or other 'real work'. Constructors are a special corner case of the language, and they basically lack the ability to do error handling.

- 187
- 2
-
This answer is "Clean Code" certified! +1 for the last paragraph. The only downside, though, is that it might not be trivial to construct this object in certain places, say in a container, if the constructing code is templatized, or expects objects to be trivially-constructed – Timor Gruber Aug 08 '21 at 20:18