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?
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.
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 providing operator bool() const or similar integral conversion), but then you don't have x in scope to query for details of the error. This may be familiar from e.g. if (std::ifstream f(filename)) { ... } else ...;
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.)
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 of optional<T> that can be invalid, T that can't. A (member or global) function that works only on valid objects works on T. One that surely returns valid works on T. One that might return an invalid object return optional<T>. One that might invalidate an object take non-const optional<T>& or optional<T>*. This way, you won't need to check in each and every function that your object is valid (and those ifs 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 an optional<>, but requires two constructions and messes up your invariant.
Take bool& succeed: This was what we were doing before optional<>. The reason optional<> is superior, you cannot mistakenly (or carelessly!) ignore the succeed 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();
}
/*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;
});
}
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...
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 ( );
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
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.
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.
Related
template<class T>
T Stack<T>::pop()
{
if (vused_ == 0)
{
throw "Popping empty stack";
}
else
{
T result = v_[used_ - 1];
--vused_;
return result;
}
}
I didn't understand all of it, or rather I understood none of it, but it was said that this code doesn't work, because it returns by value, I am guessing he was referring to result, and that calls the copy constructor and I have no idea how that's even possible. Can anyone care to explain?
Unlike the code in the question's example, std::stack<T>::pop does not return a value.
That's because if the item type needs to be copied, and the copying throws, then you have an operation failure that has changed the state of the object, with no means of re-establishing the original state.
I.e. the return-a-value-pop does not offer a strong exception guarantee (either succeed or no change).
Similarly, throwing a literal string is unconventional to say the least.
So while the code doesn't have any error in itself (modulo possible typing errors such as vused_ versus v_ etc.), it's weak on guarantees and so unconventional that it may lead to bugs in exception handling elsewhere.
A different viewpoint is that the non-value-returning pop of std::stack is impractical, leading to needlessly verbose client code.
And for using a stack object I prefer to have a value-returning pop.
But it's not either/or: a value-returning convenience method popped can be easily defined in terms of pop (state change) and top (inspection). This convenience method then has a weaker exception guarantee. But the client code programmer can choose. :-)
An improvement within the existing design would be to support movable objects, that is, replace
return result;
with
return move( result );
helping the compiler a little.
↑ Correction:
Actually, the above deleted text has the opposite effect of the intended one, namely, it inhibits RVO (guaranteeing a constructor call). Somehow my thinking got inverted here. But as a rule, don't use move on a return expression that is just the name of a non-parameter automatic variable, because the default is optimization, and the added move can not improve things, but can inhibit an RVO optimization.
Yes, returning by value formally calls the copy constructor. But that's not a problem at all, because in practice, compilers will typically be able to optimize away the additional copy. This technique is called "Return-Value Optimization".
More than the return statement (which can work if the class is movable but not copyable, e.g. you can return std::unique_ptrs), the problem is the copy you do here:
T result = v_[used_ - 1];
To make this copy possible, the type T must be copyable (e.g. T should have public copy constructor - required by the above statement - and copy assignment operator=).
As a side note, throwing a string is really bad: you should throw an exception class, e.g.
throw std::runtime_error("Popping empty stack.");
or just define an ad hoc class for this case and throw it, e.g.:
class StackUnderflowException : public std::runtime_error
{
public:
StackUnderflowException()
: std::runtime_error("Popping empty stack.")
{ }
};
....
throw StackUnderflowException();
Suppose I have things like:
class obj001
{
public:
obj001() {
std::cout << "ctor == obj001" << std::endl;
}
~obj001() {
std::cout << "dtor == obj001" << std::endl;
}
};
class obj002
{
public:
obj002() {
std::cout << "ctor == obj002" << std::endl;
}
~obj002() {
std::cout << "dtor == obj002" << std::endl;
}
};
class packet001
{
public:
packet001(): p01(NULL), p02(NULL) {
/*p01 = new obj001;
p02 = new obj002;
throw "hahaha";*/
std::cout << "CTOR == PACKET01" << std::endl;
}
~packet001() {
delete p01;
delete p02;
std::cout << "DTOR == PACKET01" << std::endl;
}
void init() {
p01 = new obj001;
p02 = new obj002;
throw "hahaha";
}
obj001* p01;
obj002* p02;
};
And if I do:
try
{
packet001 superpack;
superpack.init();
}
catch(char* type)
{
}
Then the init() failed, and the Dtor of superpack will be called.
But if I put memory allocation inside the Ctor of superpack,
(And do not execute init(), of course)
then after the Ctor failed, the Dtor will not be called, so p01 and p02 are leaked.
So, it it better to use things like init()?
Thanks!
Using two phase construction, ordinary construction followed by an outside call to an initfunction, means that after construction you don't know yet whether you have a valid object at hand. And that means that in any function that gets such an object as argument, you don't know whether the object is valid. This means a lot of extra checking and uncertainty which in turn means bugs and added work, so, a constructor should instead establish a fully functional, valid object.
The set of assumptions that go into the notion of "functional, valid" is called the class invariant.
So in other words, more academic phrasing, the job of a constructor is to establish the class invariant, so that it’s known to hold after construction.
Then keeping the object valid in every externally available operation, means that it will continue to be guaranteed valid. Thus no further validity checking is required. This scheme isn’t entirely 100% applicable to all objects (a counter-example is an object representing a file, where any operation might cause the object to become effectively invalid), but mostly it’s a good idea and works well, and where it doesn't work directly, it works for the parts.
So in your constructor you should ensure cleanup by one of the following means:
Use standard library containers (or 3rd party ones) instead of dealing directly with raw arrays and dynamic allocation.
Or use sub-objects that each manage just one resource. A sub-object can be a data member or a base class. If a data member, it can be smart pointer.
Or in the worst case, use try-catch for direct cleanup.
It’s also technically possible to use the C idea of checking return values to invoke direct cleanup as necessary. But the list above is in order of decreasing ease and safety. The C style coding is somewhere beyond the bottom of that list.
The C++ language creator, Bjarne Stroustrup, has written a little about this very subject, in his appendix Appendix E: Standard-Library Exception Safety appendix to the 3rd edition of The C++ Programming Language. Just download the PDF, and in your PDF reader search for “init(”. You should land directly a bit into section §E3.5, about Constructors and Invariants; do read on through at least section §E.3.5.1 about Using init() Functions.
As Bjarne lists there, …
[…] having a separate init() function is an opportunity to
[1] forget to call init() (§10.2.3),
[2] forget to test on the success of init(),
[3] call init() more than once,
[4] forget that init()might throw an exception, and
[5] use the object before calling init().
Bjarne’s discussion is, I think, great for a beginner, as is the whole book.
However, be aware that a common reason for two-phase construction, namely to support derived class specific initialization, is simply not mentioned at all, not part of Bjarne’s picture here. This is the reason for two-phase initialization in many GUI frameworks. Some C++ GUI frameworks with OK single phase initialization do exist, however, proving that mostly it was all an educational issue – that those early C++ programmers simply did not know about, or could not assume that their library users would understand, C++ RAII.
The best thing is to avoid these kinds of allocations altogether. You can put instances directly within a class for many things. If you really need a pointer, you can use unique_ptr and shared_ptr for automatic memory management.
In your example, this would be fine:
struct packet001
{
obj001 p01;
obj002 p02;
};
If you need them to be pointers:
struct packet001
{
packet001()
: p01(new obj001),
p02(new obj002)
{
}
std::unique_ptr<obj001> p01;
std::unique_ptr<obj002> p02;
};
The memory will automatically be freed in the destructor, and deallocations will happen properly if an exception occurs during construction.
Shouldn't you catch all exceptions in Ctor and clean up properly if exceptions arrive inside Ctor?
I have used two phase construction, or various other means pointed out for in constructor cleanup, in instances where the constructor is likely to fail many a times AND where I want the program to continue to run even after that failure; e.g. trying to construct an object that reads a file, where the file name was provided by the user. There the constructor is likely to fail many a times, e.g. on bad user input.
But bad_alloc - that should be rare for a well designed program. And what exactly are you going to do if the memory allocation fails? Your C++ program is most likely doomed at that point of time. Why worry about a memory leak at that point of time? Now you can point out some counter examples where programs can continue to run even after encountering a bad alloc, OR programs which employ fancy techniques to avoid bad_allocs, but is your program one of those?
I'm currently in charge of finding all bad practices in our code base and to convince my colleagues to fix the offending code. During my spelunking, I noticed that many people here use the following pattern:
class Foo
{
public:
Foo() { /* Do nothing here */ }
bool initialize() { /* Do all the initialization stuff and return true on success. */ }
~Foo() { /* Do all the cleanup */ }
};
Now I might be wrong, but to me this initialize() method thing is awful. I believe it cancels the whole purpose of having constructors.
When I ask my collegues why this design decision was made, they always answer that they have no choice because you can't exit a constructor without throwing (I guess they assume throwing is always bad).
I failed to convince them so far and I admit I may lack of valuable arguments... so here is my question: Am I right that this construct is a pain and if so, what issues do you see in it ?
Thank you.
Both single step (constructor) initialisation and two step (with an init method) initialisation are useful patterns. Personally I feel that excluding either is a mistake, although if your conventions prohibit use of exceptions entirely then you prohibit single step initialisation for constructors that can fail.
In general I prefer single step initialisation because this means that your objects can have
stronger invariants. I only use two step initialisation when I consider it meaningful or useful for an object to be able to exist in an "uninitialised" state.
With two step initialisation it is valid for your object to be in an uninitialised state - so every method that works with the object needs to be aware of and correctly handle the
fact that it might be in an uninitialised state. This is analogous to working with pointers, where it is poor form to assume that a pointer is not NULL. Conversely, if you do all your initialisation in your constructor and fail with exceptions than you can add 'the object is always initialised' to your list of invariants, and so it becomes easier and safer to
make assumptions about the state of the object.
This is usually known as Two phase or Multiphase Initialization and it is particularly bad because once a constructor call has finished successfully, you should have a ready to use object, In this case you won't have a ready-to-use object.
I cannot help but stress more on the following:
Throwing an exception from constructor in case of failure is the best and the only concise way of handling object construction failures.
It depends on the semantics of your object. If the initialization is something that's crucial to the data structure of the class itself, then a failure would be better handled by either throwing an exception from the constructor (e.g. if you are out of memory), or by an assertion (if you know that your code should not actually fail, ever).
On the other hand, if success or otherwise of the construction depends on user input, then failure is not an exceptional condition, but rather part of the normal, expected runtime behaviour that you need to test for. In that case, you should have a default constructor that creates an object in an "invalid" state, and an initialization function that can be called either in a constructor or later and that may or may not succeed. Take std::ifstream as an example.
So a skeleton of your class could look like this:
class Foo
{
bool valid;
bool initialize(Args... args) { /* ... */ }
public:
Foo() : valid(false) { }
Foo(Args... args) : valid (false) { valid = initialize(args...); }
bool reset(Args... args) // atomic, doesn't change *this on failure
{
Foo other(args...);
if (other) { using std::swap; swap(*this, other); return true; }
return false;
}
explicit operator bool() const { return valid; }
};
It depends on the case.
If a constructor can fail because of some arguments, an exception should be thrown. But, of course, you need to document yourself on throwing exceptions from constructors.
If Foo contains objects, they will be initialized twice, once in the constructor, once in the initialize method, so that's a drawback.
IMO, the biggest drawback is that you have to remember to call initialize. What's the point of creating an object if it's invalid?
So, if their only argument is that they don't want to throw exceptions from the constructor, it's a pretty bad argument.
If, however, they want some sort of lazy initialization, it's valid.
It is a pain, but you have no other choice if you want to avoid throwing exception from constructor. There is also another option, equally painful: do all initialization in the constructor and then you have to check if the object has been constructed succefully (e.g. conversion operator to bool or IsOK method). Life is hard, ..... and then you die :(
I realise this is a very old thread, but I wanted to add something that hasn't been explicitly stated (or is perhaps simply implied). In C++, when a constructor throws an exception, the object is not considered "constructed" and therefore its destructor will not get called as part of the exception unwinding.
This can be a very real motivating factor for having an initialise( ) method instead of doing it in the constructor. A complex object doing lots of memory allocation and the like would have to unwind all that work manually if the constructor threw an exception.
If an initialise( ) method is used, the object is already "constructed" at the time of initialisation, and hence the object's destructor will be called.
So, yes, doing the initialisation in the constructor is "nicer", but it also puts a greater burden on the programmer to clean up properly if things go wrong. A piecemeal approach to cleaning up will make for very ugly code.
In some cases, therefore, it might be better to accept pragmatism over idealism.
When an object is constructed, it must be ready to use.
most SDK developers forgot this rule, and they expect to call another method named initialize to complete setup because they have to do some async tasks to construct object, but problem is constructors can't be async.
the solution is you should set constructor private, so no one can initialize the object. then add an static method which returns an instance of the object asynchronously.
here is an example in dart:
class FacetecPlugin {
final String _token;
// Ensures end-users cannot initialize the class.
FacetecPlugin._privateConstructor({required String token}) : _token = token;
Future<void> checkLiveness() async {
await FacetecPlatform.instance.checkLiveness(_token);
}
//This is method should be called before any usage of FacetecPlugin plugin.
static Future<FacetecPlugin> initialize(Configuration config) async {
final initialized = await FacetecPlatform.instance.initialize(
deviceKeyIdentifier: config.deviceKey,
publicEncryptionKey: config.publicEncryptionKey);
if (!initialized) {
throw Exception('Facetec SDK initialization failed.');
}
final token = await _getSessionToken(config);
// creating an instance of the plugin with token and returning it.
return FacetecPlugin._privateConstructor(token: token);
}
# other methods have been omitted for brevity.
Now user can't construct the plugin directly. but he has to use initialize method which return a properly constructed plugin and is ready to use.
// final facetecPlugin = FacetecPlugin() // can't be called. constructor is private
final facetecPlugin = await FacetecPlugin.initialize(Configuration(deviceId:'1234'));
final result = await facetecPlugin.checkLiveness()
What's a good existing class/design pattern for multi-stage construction/initialization of an object in C++?
I have a class with some data members which should be initialized in different points in the program's flow, so their initialization has to be delayed. For example one argument can be read from a file and another from the network.
Currently I am using boost::optional for the delayed construction of the data members, but it's bothering me that optional is semantically different than delay-constructed.
What I need reminds features of boost::bind and lambda partial function application, and using these libraries I can probably design multi-stage construction - but I prefer using existing, tested classes. (Or maybe there's another multi-stage construction pattern which I am not familiar with).
The key issue is whether or not you should distinguish completely populated objects from incompletely populated objects at the type level. If you decide not to make a distinction, then just use boost::optional or similar as you are doing: this makes it easy to get coding quickly. OTOH you can't get the compiler to enforce the requirement that a particular function requires a completely populated object; you need to perform run-time checking of fields each time.
Parameter-group Types
If you do distinguish completely populated objects from incompletely populated objects at the type level, you can enforce the requirement that a function be passed a complete object. To do this I would suggest creating a corresponding type XParams for each relevant type X. XParams has boost::optional members and setter functions for each parameter that can be set after initial construction. Then you can force X to have only one (non-copy) constructor, that takes an XParams as its sole argument and checks that each necessary parameter has been set inside that XParams object. (Not sure if this pattern has a name -- anybody like to edit this to fill us in?)
"Partial Object" Types
This works wonderfully if you don't really have to do anything with the object before it is completely populated (perhaps other than trivial stuff like get the field values back). If you do have to sometimes treat an incompletely populated X like a "full" X, you can instead make X derive from a type XPartial, which contains all the logic, plus protected virtual methods for performing precondition tests that test whether all necessary fields are populated. Then if X ensures that it can only ever be constructed in a completely-populated state, it can override those protected methods with trivial checks that always return true:
class XPartial {
optional<string> name_;
public:
void setName(string x) { name_.reset(x); } // Can add getters and/or ctors
string makeGreeting(string title) {
if (checkMakeGreeting_()) { // Is it safe?
return string("Hello, ") + title + " " + *name_;
} else {
throw domain_error("ZOINKS"); // Or similar
}
}
bool isComplete() const { return checkMakeGreeting_(); } // All tests here
protected:
virtual bool checkMakeGreeting_() const { return name_; } // Populated?
};
class X : public XPartial {
X(); // Forbid default-construction; or, you could supply a "full" ctor
public:
explicit X(XPartial const& x) : XPartial(x) { // Avoid implicit conversion
if (!x.isComplete()) throw domain_error("ZOINKS");
}
X& operator=(XPartial const& x) {
if (!x.isComplete()) throw domain_error("ZOINKS");
return static_cast<X&>(XPartial::operator=(x));
}
protected:
virtual bool checkMakeGreeting_() { return true; } // No checking needed!
};
Although it might seem the inheritance here is "back to front", doing it this way means that an X can safely be supplied anywhere an XPartial& is asked for, so this approach obeys the Liskov Substitution Principle. This means that a function can use a parameter type of X& to indicate it needs a complete X object, or XPartial& to indicate it can handle partially populated objects -- in which case either an XPartial object or a full X can be passed.
Originally I had isComplete() as protected, but found this didn't work since X's copy ctor and assignment operator must call this function on their XPartial& argument, and they don't have sufficient access. On reflection, it makes more sense to publically expose this functionality.
I must be missing something here - I do this kind of thing all the time. It's very common to have objects that are big and/or not needed by a class in all circumstances. So create them dynamically!
struct Big {
char a[1000000];
};
class A {
public:
A() : big(0) {}
~A() { delete big; }
void f() {
makebig();
big->a[42] = 66;
}
private:
Big * big;
void makebig() {
if ( ! big ) {
big = new Big;
}
}
};
I don't see the need for anything fancier than that, except that makebig() should probably be const (and maybe inline), and the Big pointer should probably be mutable. And of course A must be able to construct Big, which may in other cases mean caching the contained class's constructor parameters. You will also need to decide on a copying/assignment policy - I'd probably forbid both for this kind of class.
I don't know of any patterns to deal with this specific issue. It's a tricky design question, and one somewhat unique to languages like C++. Another issue is that the answer to this question is closely tied to your individual (or corporate) coding style.
I would use pointers for these members, and when they need to be constructed, allocate them at the same time. You can use auto_ptr for these, and check against NULL to see if they are initialized. (I think of pointers are a built-in "optional" type in C/C++/Java, there are other languages where NULL is not a valid pointer).
One issue as a matter of style is that you may be relying on your constructors to do too much work. When I'm coding OO, I have the constructors do just enough work to get the object in a consistent state. For example, if I have an Image class and I want to read from a file, I could do this:
image = new Image("unicorn.jpeg"); /* I'm not fond of this style */
or, I could do this:
image = new Image(); /* I like this better */
image->read("unicorn.jpeg");
It can get difficult to reason about how a C++ program works if the constructors have a lot of code in them, especially if you ask the question, "what happens if a constructor fails?" This is the main benefit of moving code out of the constructors.
I would have more to say, but I don't know what you're trying to do with delayed construction.
Edit: I remembered that there is a (somewhat perverse) way to call a constructor on an object at any arbitrary time. Here is an example:
class Counter {
public:
Counter(int &cref) : c(cref) { }
void incr(int x) { c += x; }
private:
int &c;
};
void dontTryThisAtHome() {
int i = 0, j = 0;
Counter c(i); // Call constructor first time on c
c.incr(5); // now i = 5
new(&c) Counter(j); // Call the constructor AGAIN on c
c.incr(3); // now j = 3
}
Note that doing something as reckless as this might earn you the scorn of your fellow programmers, unless you've got solid reasons for using this technique. This also doesn't delay the constructor, just lets you call it again later.
Using boost.optional looks like a good solution for some use cases. I haven't played much with it so I can't comment much. One thing I keep in mind when dealing with such functionality is whether I can use overloaded constructors instead of default and copy constructors.
When I need such functionality I would just use a pointer to the type of the necessary field like this:
public:
MyClass() : field_(0) { } // constructor, additional initializers and code omitted
~MyClass() {
if (field_)
delete field_; // free the constructed object only if initialized
}
...
private:
...
field_type* field_;
next, instead of using the pointer I would access the field through the following method:
private:
...
field_type& field() {
if (!field_)
field_ = new field_type(...);
return field_;
}
I have omitted const-access semantics
The easiest way I know is similar to the technique suggested by Dietrich Epp, except it allows you to truly delay the construction of an object until a moment of your choosing.
Basically: reserve the object using malloc instead of new (thereby bypassing the constructor), then call the overloaded new operator when you truly want to construct the object via placement new.
Example:
Object *x = (Object *) malloc(sizeof(Object));
//Use the object member items here. Be careful: no constructors have been called!
//This means you can assign values to ints, structs, etc... but nested objects can wreak havoc!
//Now we want to call the constructor of the object
new(x) Object(params);
//However, you must remember to also manually call the destructor!
x.~Object();
free(x);
//Note: if you're the malloc and new calls in your development stack
//store in the same heap, you can just call delete(x) instead of the
//destructor followed by free, but the above is the correct way of
//doing it
Personally, the only time I've ever used this syntax was when I had to use a custom C-based allocator for C++ objects. As Dietrich suggests, you should question whether you really, truly must delay the constructor call. The base constructor should perform the bare minimum to get your object into a serviceable state, whilst other overloaded constructors may perform more work as needed.
I don't know if there's a formal pattern for this. In places where I've seen it, we called it "lazy", "demand" or "on demand".
I have a case in which I have to read an input file in the C'tor, but sometimes this file doesn't exist.
This object is usually held statically, so its C'tor is called while loading the dll.
I can't catch the exception I throw if the file doesn't exist because it's too early, and my executable crashes in an ugly way.
I know it's bad practice to throw exceptions out of a C'tor, but I can't go on if the file doesn't exist, so I have to.
Is there a way to catch the exception while loading the dll, and if not, is there any better solution for this scenario?
Thanks,
Gal
I assume the static object has the file scope (it is outside any function/class definition). You may consider moving it to an accessor function and accessing it only via that function, like this:
class Object;
Object& getObject()
{
static Object object;
return object;
}
The static instance of Object will be initialized upon the first calling of the getObject() method. If the Object's constructor throws, you can easily catch the exception. Just you need to remember wrapping every call of getObject() into a try/catch block (or suffer from the exception bubbling up the stack chain); that may be a bit inconvenient, but on the other hand you may decide to wrap just the logically "first" call, if you know which one it is in the program logic flow.
Throwing exceptions out of a constructor is not necessarily a bad practice. In fact, RAII usually requires you to do this sort of things, because objects have an internal invariant that must be satisfied, and if the constructor can't initialize the object and leave it in a valid state, then it's the only way to go.
Throwing exceptions from a destructor, on the other hand, is a bad practice (and also a dangerous one). But throwing them from a constructor should be OK.
If you can use c++11 then there is a lambda and unique_ptr<> solution to this:
// In some_file.hpp
#pragma once
#include <memory>
#include <stdexcept>
class CtorThrows {
public:
CtorThrows (int value) {
if (value < 10) {
throw std::runtime_error("oops!");
}
}
};
class ClassWithStatic {
public:
private:
static std::unique_ptr<CtorThrows> bad_member_; // <-- static member
};
and then
// In some_file.cpp
#include "some_file.hpp"
// Create a lambda function to initialize the static member variable.
std::unique_ptr<CtorThrows> ClassWithStatic::bad_member_ = []() {
try {
int value = 5; // in this case, it is a bad value
// This only returns successfully if bad_value DOESN'T cause
// the ctor to throw and exception.
return std::make_unique<CtorThrows>(value);
} catch (std::runtime_error &e) {
std::cerr << "OOPs! Here's a nice error message" << std::endl;
exit(1);
}
return std::unique_ptr<CtorThrows>(nullptr);
}();
Using a unique_ptr lets you do this even with classes with that have a deleted or private copy constructor and copy assignment operator.
Redesign the object in such a way that it opens the file later - for example when the data from the file is requested the first time.
Alternatively replase the static object with a static pointer and call new when needed. It's better to use a smart pointer like auto_ptr.
How about separating reading the input file from the Constructor? You could have a separate Init() Method that must be called after constructing the object but before the object is actually ready to use.
You're right that you can't catch exeptions that happen during the initialization of static objects.
Since you're writing a DLL: Each DLL can have an entry-point, and inside this entry point exception handling works. (It's the same as main in your main-program). I'd remove the static instances of your classes, replace them with pointers and initialize these pointers inside dllmain.
That'll solve your problems once for all.
Btw - the DLL entrypoint gets called on load, unload and other events such as process attach/detach ect. Be sure you use the correct place to initialize your classes.
One way may be to "design" this to make the calling code (i.e. the code outside the dll) responsible for making sure all dependencies of the dll is in place. A function in the calling code that makes sure the dll's dependencies, in this case the file, is in place and is loadable before loading the library. If not, it can gracefully exit.