People say that is a bad technique to throw exception from
constructors; and that the solution would be to create a function
_create_ to initialize an object.
What about copy constructors? How can we avoid throwing exceptions? If
we already have an abject witch was initialized wit _create_ we will be
forced to call create in copy constructor and to throw exceptions from
it.
Have a nice day,
Mihai. 21 4202
>People say that is a bad technique to throw exception from constructors
In an ideal world, constructors would never throw. In the real world,
that's not the case. Whether bad technique or not (I won't step on a
slippery slope like that), a non-trivial class will likely see a
situation where it could need to catch an exception caused by
construction of either a base class or one of the data members, and not
be able to reasonably handle it.
What would you do in that case? Complain that throwing from
constructors is bad style and do nothing? Sure, you could use a create
function to initialize the object, but if you call it in the
constructor and it throws, you're back to square one. That leaves
calling it outside of the constructor, which basically means that you
either require the client code to call it (a dangerous plan), or you
work out some ugly hack where create is only called for the first use
beyond the constructor.
What about default initialization? It's feasable that default
initialization could fail, and since that constitutes an exceptional
situation, the constructor could throw (bad style or not). So you find
yourself between a rock and a hard place with the ideal world and the
real world. And here's the bad news: The real world always wins.
This includes the copy constructor and in some cases the assignment
operator as well. I hate to say that you're SOL, but them's the breaks.
"mihai" <Mi*********@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object.
What about copy constructors? How can we avoid throwing exceptions? If we already have an abject witch was initialized wit _create_ we will be forced to call create in copy constructor and to throw exceptions from it.
I don't believe that well-informed people say constructors shouldn't throw.
They do say that *destructors* shouldn't throw.
The throwing of an exception by a constructor can cause a problem because it
means that the destructor is not called, which may mean that necessary
cleanup doesn't occur.
The standard way to handle this is to wrap anything in class A that needs to
be cleaned up in a class of its own (say, classes B, C and D) and then make
objects of those classes (say, b, c and d) members of A. The initialisation
of b, c and d can then occur in A's constructor (via the initialisation
list). If, say, the initialisation of d causes an exception, then b and c
will have been fully constructed (unlike the A object) and hence their
destructors will be called, even though the A object's constructor won't be.
This achieves the necessary cleanup.
The C++ FAQ on Exceptions and Error Handling has some useful stuff on this: http://www.parashift.com/c++-faq-lite/exceptions.html
--
John Carson
IMHO, that's silly ( saying that it's bad technique to throw from a
constructor ). What other mechanism is there to know if something goes
wrong with contructing an object? You can't return an error code from
the constructor, all you can do is throw an exception. Who said that
this is bad technique anyway?
* BigBrian: IMHO, that's silly ( saying that it's bad technique to throw from a constructor ).
Yes.
What other mechanism is there to know if something goes wrong with contructing an object?
An infinite number... ;-)
You can't return an error code from the constructor, all you can do is throw an exception.
Nope.
class Silly
{
private:
bool iAmValid;
public:
Silly( int x, bool& ok ): iAmValid( x == 42 )
{
ok = iAmValid;
}
};
The reason why this _particular_ technique is bad is mainly that you risk
having invalid objects hanging around, so called ZOMBIE OBJECTS, which
necessitates much redundant checking of validity and leads to bugs.
Formally it's a kind of meta, second-level class invariant.
Worth noting: languages like Java and C# typically force you to have
zombie objects but in those languages the problem arises from the other end
of the object lifecycle, destruction. Because you don't have deterministic
destruction in those languages the programmer must call Dispose (or like)
methods explicitly, and the objects still exist afterwards. And so must
note for themselves that they're no longer valid, and so they're zombies
and can conceivably become zombies earlier on.
Also worth noting: handling of external resources in some cases require
zombie states. E.g., a file can become invalid at any time. An object
wrapping that file is then logically invalid for at least part of its
interface, a zombie object wrt. to the invalid parts of the interface.
Who said that [throwing an exception] is bad technique anyway?
Yes. Anyone worth listening to will tell the opposite. A clear but
limited discussion of why using exceptions in constructors, avoiding
zombie states, is given in Bjarne Stroustrup's TCPPPL appendix on
exception safety in the standard library, available as a PDF document
at <url: http://www.research.att.com/~bs/3rd_safe0.html>.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
"mihai" <Mi*********@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com... People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object.
The so called bad technique is throwing exception from destructors, not
constructors. What about copy constructors? How can we avoid throwing exceptions? If we already have an abject witch was initialized wit _create_ we will be forced to call create in copy constructor and to throw exceptions from it.
There are many ways like turning your object into a zombie state. Read the
FAQ, it describes some of the techniques.
Of course, throwing exceptions from copy consturcotrs is what most would
recommend. Have a nice day, Mihai.
Yes, I guess somebody could do something like your Silly class, however
since it has problems I didn't consider this when I made my statement
about "what other mechanism exist (for notifying the client code that
an error has occured in a constructor)". In using the Silly class, the
calling code may not check the pass by reference value into this
constructor. Also, the silly class will need a bunch of if tests
throughout it's implementation.
Since you said there are infinitely many ways to provide this
mechanism, and the Silly class is clearly not the way to do it. Please
provide another method which is better than throwing an exception.
I understand that some objects need memebers to keep track of some sort
of state, and that state may at times be invalid. This is different
than error conditions which need to throw exceptions to notify the
calling code that something is wrong.
>The so called bad technique is throwing exception from destructors, not
constructors.
I thought throwing an exception from a destructor was *MUCH* worse than
bad technique, it's plain outright WRONG. Aren't destructors REQUIRED
to NOT throw?
* BigBrian: Yes, I guess somebody could do something like your Silly class, however since it has problems I didn't consider this when I made my statement about "what other mechanism exist (for notifying the client code that an error has occured in a constructor)". In using the Silly class, the calling code may not check the pass by reference value into this constructor. Also, the silly class will need a bunch of if tests throughout it's implementation.
That's about right.
Since you said there are infinitely many ways to provide this mechanism, and the Silly class is clearly not the way to do it. Please provide another method which is better than throwing an exception.
You'll need to define "better" first.
But it's evident that you've misunderstood and skipped some points, so
there's no real need for that: do read my posting again.
I understand that some objects need memebers to keep track of some sort of state, and that state may at times be invalid.
Yes, sort of.
This is different than error conditions which need to throw exceptions to notify the calling code that something is wrong.
No, it's all about convenience, maintainability, productivity and so forth.
There's no absolute "need", just as there is no absolute "better". Those
are subjective, contextual judgements, not technical facts, although I
agree that concerning this issue you'd need very strong reasons for using
anything but exceptions and be able to justify it to someone competent.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
* BigBrian: The so called bad technique is throwing exception from destructors, not constructors.
I thought throwing an exception from a destructor was *MUCH* worse than bad technique, it's plain outright WRONG. Aren't destructors REQUIRED to NOT throw?
No.
But a destructor for an object used in a standard collection is required
to not throw.
That's also the case for exception object destructors... ;-)
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
>No. But a destructor for an object used in a standard collection is required to not throw.
I don't this this is strict enough. Most techniques for writing
exception safe code assumes that destructors to NOT throw.
>You'll need to define "better" first.
It was implied that "better" meant without the stated problems with
your "Silly" class. But it's evident that you've misunderstood and skipped some points, so, there's no real need for that: do read my posting again.
You (arogantly) said there were infinate ways to do this, and now you
won't provide another mechanism?
No, it's all about convenience, maintainability, productivity and so forth. There's no absolute "need", just as there is no absolute "better".
If the need to inform the user of a class that an error has occured is
a *requirement*, then there *is* an absolute need. This brings us back
to the issue... How else can you *guarentee* that the user of your
class knows (without a doubt) that an error has occured. Requiring the
user of your class to check a flag isn't good enough (due to the issues
that we already discoussed). What are the infinitely many other ways
to guarentte this is accomplish without throwing an exception?
* BigBrian: No.
But a destructor for an object used in a standard collection is required to not throw.
I don't this this is strict enough. Most techniques for writing exception safe code assumes that destructors to NOT throw.
You asked: "Aren't destructors REQUIRED to NOT throw?".
You get an answer to that, not to something else that you even now aren't
telling what is.
Please don't use all caps, please don't quote out of context, please
don't add your own imagined context to responses (I at least am not a
telepath: I don't know what the heck you're talking about).
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
* BigBrian: You'll need to define "better" first. It was implied that "better" meant without the stated problems with your "Silly" class.
But it's evident that you've misunderstood and skipped some points, so, there's no real need for that: do read my posting again.
You (arogantly) said there were infinate ways to do this
The part "said there were infinate ways to do this" is a lie; the
"arogantly" is meaningless applied to something that hasn't happened.
Don't lie, don't insinuate.
You asked: "What other mechanism is there to know if something goes
wrong with contructing an object?"
You got the answer: "An infinite number... ;-)"
These include the Silly class way, abort, callback, global status
variable, factory with null-pointer result, even writing the result
to a file or sending an e-mail -- use your imagination.
and now you won't provide another mechanism?
If you can be more clear about the C++ question, I'll try to help you. No, it's all about convenience, maintainability, productivity and so forth. There's no absolute "need", just as there is no absolute "better".
If the need to inform the user of a class that an error has occured is a *requirement*, then there *is* an absolute need. This brings us back to the issue... How else can you *guarentee* that the user of your class knows (without a doubt) that an error has occured. Requiring the user of your class to check a flag isn't good enough (due to the issues that we already discoussed). What are the infinitely many other ways to guarentte this is accomplish without throwing an exception?
There are _no_ ways that guarantee that.
In particular, an exception doesn't guarantee that; client code can
always nullify any guarantee you think you have.
Foo* p; try{ p = new Foo; } catch(...){}
// No guarantee here.
Hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
On 2005-06-02 09:04:34 -0400, "John Carson"
<jc****************@netspace.net.au> said: "mihai" <Mi*********@gmail.com> wrote in message news:11**********************@g44g2000cwa.googlegr oups.com People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object.
What about copy constructors? How can we avoid throwing exceptions? If we already have an abject witch was initialized wit _create_ we will be forced to call create in copy constructor and to throw exceptions from it.
I don't believe that well-informed people say constructors shouldn't throw. They do say that *destructors* shouldn't throw.
The throwing of an exception by a constructor can cause a problem because it means that the destructor is not called, which may mean that necessary cleanup doesn't occur.
Just to clarify, the destructor of that class isn't called, but the
destructors of any already constructed superclasses are.
The standard way to handle this is to wrap anything in class A that needs to be cleaned up in a class of its own (say, classes B, C and D) and then make objects of those classes (say, b, c and d) members of A. The initialisation of b, c and d can then occur in A's constructor (via the initialisation list). If, say, the initialisation of d causes an exception, then b and c will have been fully constructed (unlike the A object) and hence their destructors will be called, even though the A object's constructor won't be. This achieves the necessary cleanup.
The C++ FAQ on Exceptions and Error Handling has some useful stuff on this:
http://www.parashift.com/c++-faq-lite/exceptions.html
--
Clark S. Cox, III cl*******@gmail.com
>The part "said there were infinate ways to do this" is a lie; the "arogantly" is meaningless applied to something that hasn't happened.
What! This isn't a lie. Here is a quote from one of your previous
message....
I wrote this.... What other mechanism is there to know if something goes wrong with contructing an object?
And you wrote this...An infinite number... ;-)
>In particular, an exception doesn't guarantee that; client code can always nullify any guarantee you think you have.
Foo* p; try{ p = new Foo; } catch(...){} // No guarantee here.
That's true. But in this case the user of the class has to
specifically add the above code to ignore the exception. In the case
of checking a return value, you have to specificially add code to check
it. It could be easy for the user of the class to forget to check for
an error. Thus, having to add code to say "I'm not intrested in your
error" is BETTER than writting code such that doing nothing saying same
thing ( as with an error flag ).
* BigBrian: The part "said there were infinate ways to do this" is a lie; the "arogantly" is meaningless applied to something that hasn't happened.
What! This isn't a lie. Here is a quote from one of your previous message....
I wrote this.... What other mechanism is there to know if something goes wrong with contructing an object?
And you wrote this...An infinite number... ;-)
Ergo, you lied.
In addition to don't lie and don't insinuate:
Don't quote out of context.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
* BigBrian: In particular, an exception doesn't guarantee that; client code can always nullify any guarantee you think you have.
Foo* p; try{ p = new Foo; } catch(...){} // No guarantee here.
That's true. But in this case the user of the class has to specifically add the above code to ignore the exception. In the case of checking a return value, you have to specificially add code to check it. It could be easy for the user of the class to forget to check for an error. Thus, having to add code to say "I'm not intrested in your error" is BETTER than writting code such that doing nothing saying same thing ( as with an error flag ).
Add a "usually" and that will be generally true.
However there are many ways the client code can foul up, e.g.
int x = 1;
std::cout << x++ << "," << x << std::endl;
// We have Undefined Behavior, so no guarantee here:
Foo object;
No matter which method is employed one can only help the client code
programmer, one can not guarantee correct client code. And with that
perspective what constitutes the best help depends on the client code
programmer. And much else.
As an example of relevant purely technical consideration, in language
agnostic code such as the basic COM infrastructure it's not possible
to throw C++ exceptions out of the the interface the client code uses,
since the client code language may not understand them. So this is a
situation where exceptions are not clearly "better". For this example
exceptions are most probably "worse"... ;-)
At a higher level, with a good choice of error reporting mechanism C++
exceptions can be added on top, in a wrapper layer, for C++ client code.
The reverse, starting out with C++ exceptions and wrapping them, would
introduce a possible internal overhead for no gain. What's "better"
and "worse" is therefore highly contextual, not absolutes.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
mihai wrote: People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object.
Which people? Provided you know what you are doing, there is no problem.
What about copy constructors? How can we avoid throwing exceptions? If we already have an abject witch was initialized wit _create_ we will be forced to call create in copy constructor and to throw exceptions from it.
It's more important to be exception-neutral. You can't avoid exceptions
(e.g. std::bad_alloc), and you can't in general control what other
classes decide to throw. The best you can hope to do is to recover
safely. Exception-neutrality means that you will safely pass through
exceptions to the caller, which is in general what you want.
Fantastic tools for exception safety are std::auto_ptr and swap. swap
does not throw. The assignment operator should (ideally) not leave the
object in a half-copied state in the face of an exception.
e.g. Here is an exception-neutral class. If allocation fails, or any of
the constructors throw, the class performs the correct clean-up.
class C
{
std::auto_ptr<X> x;
std::auto_ptr<Y> y;
public:
C(const C &c) : x(new X(*c.x)), y(new Y(*c.y))
{
}
C& operator=(const C &c)
{
std::auto_ptr<X> new_x(new X(*c.x));
std::auto_ptr<Y> new_y(new Y(*c.y));
x.swap(new_x);
y.swap(new_y);
return *this;
}
};
Have a nice day, Mihai.
* Calum Grant: e.g. Here is an exception-neutral class. If allocation fails, or any of the constructors throw, the class performs the correct clean-up.
class C { std::auto_ptr<X> x; std::auto_ptr<Y> y; public: C(const C &c) : x(new X(*c.x)), y(new Y(*c.y)) { }
For others who read this, a subtle point: this works because there's a
sequence point between each pair of initializer in the initialization list.
In a an ordinary function call it's generally not safe to have more than one
'new' in the arguments. One cure is then to wrap the allocations in
functions so that the compiler cannot choose to first allocate all objects'
memory and only then call the constructors.
Btw., there should really be some way to construct a C object... ;-)
C& operator=(const C &c) { std::auto_ptr<X> new_x(new X(*c.x)); std::auto_ptr<Y> new_y(new Y(*c.y)); x.swap(new_x); y.swap(new_y); return *this; }
Typo: you meant
std::swap( x, new_x );
std::swap( y, new_y );
(std::auto_ptr has no swap member function).
};
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
"John Carson" <jc****************@netspace.net.au> wrote in message
news:d7***********@otis.netspace.net.au The standard way to handle this is to wrap anything in class A that needs to be cleaned up in a class of its own (say, classes B, C and D) and then make objects of those classes (say, b, c and d) members of A. The initialisation of b, c and d can then occur in A's constructor (via the initialisation list). If, say, the initialisation of d causes an exception, then b and c will have been fully constructed (unlike the A object) and hence their destructors will be called, even though the A object's constructor won't be. This achieves the necessary cleanup.
Typo here:
"even though the A object's constructor won't be"
should be
"even though the A object's *destructor* won't be"
--
John Carson This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Mark Oueis |
last post by:
I've been struggling with this question for a while. What is better
design? To design functions to return error codes when an error
occures, or to have them throw exceptions.
If you chose the...
|
by: mangesh |
last post by:
I read , FAQ : 17.4] How should I handle resources if my constructors
may throw exceptions?
Above faq says that use smart pointer in construcors . Because if
exception is thrown from constructor...
|
by: Sek |
last post by:
Gurus,
I am wondering whether it is right to throw an exception from a
Property of an object.
To get into it further, is it okay to throw exception during 'get'
operation?
I was searching...
|
by: Sek |
last post by:
Is it appropriate to throw exception from a constructor?
Thats the only way i could think of to denote the failure of
constructor, wherein i am invoking couple of other classes to
initialise the...
|
by: Marvin Barley |
last post by:
I have a class that throws exceptions in new initializer, and a static
array of objects of this type.
When something is wrong in initialization, CGI program crashes
miserably. Debugging shows...
|
by: Ruben |
last post by:
Hello
I'm struggling with the throw and catch exception system. As I understood
it, when you throw an error, that the stack is searched for a matching
catch, but I'm having difficult finding...
|
by: Chris M. Thomasson |
last post by:
Is it every appropriate to throw in a dtor? I am thinking about a simple
example of a wrapper around a POSIX file...
________________________________________________________________________
class...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: WisdomUfot |
last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
|
by: Oralloy |
last post by:
Hello Folks,
I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA.
My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
|
by: BLUEPANDA |
last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
|
by: Rahul1995seven |
last post by:
Introduction:
In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: Johno34 |
last post by:
I have this click event on my form. It speaks to a Datasheet Subform
Private Sub Command260_Click()
Dim r As DAO.Recordset
Set r = Form_frmABCD.Form.RecordsetClone
r.MoveFirst
Do
If...
|
by: ezappsrUS |
last post by:
Hi,
I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
|
by: jack2019x |
last post by:
hello, Is there code or static lib for hook swapchain present?
I wanna hook dxgi swapchain present for dx11 and dx9.
| |