473,324 Members | 2,178 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

throwing exception from constructor

Sek
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 object.

TIA
Sek

Aug 1 '06 #1
40 36021
As far as i know, It's not a appropriate way to throw exception from a
constructor.
If you can make sure that when exception occured, you should dispose
all resoures, such as, File handler, memory, etc.

Sek 写道:
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 object.

TIA
Sek
Aug 1 '06 #2
Sek wrote:
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 object.
Yup, that's fine. Several framework types do it. For examples, see
Guid(string), the FileStream constructors, and String(char[], int,
int).

Jon

Aug 1 '06 #3
simida wrote:
As far as i know, It's not a appropriate way to throw exception from a
constructor.
It's widely done, and there's no reason not to do it in .NET. In
unmanaged C++ there are reasons why it's a bad idea, but they don't
apply to .NET.
If you can make sure that when exception occured, you should dispose
all resoures, such as, File handler, memory, etc.
File handles etc, yes - but memory will automatically be cleaned up by
the garbage collector.

Jon

Aug 1 '06 #4
Contructor supposed to handle simple tasks like initialization. If up to the
stage you need to throw exception from contructor I think I would suggest
you to review the code.

chanmm

"Sek" <se****@gmail.comwrote in message
news:11*********************@s13g2000cwa.googlegro ups.com...
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 object.

TIA
Sek

Aug 1 '06 #5
chanmm wrote:
Contructor supposed to handle simple tasks like initialization. If up to the
stage you need to throw exception from contructor I think I would suggest
you to review the code.
Initialization can quite often suggest throwing exceptions,
particularly based on the parameters. What would you suggest FileStream
should do if it's been asked to open a file for reading and the file
doesn't exist?

Jon

Aug 1 '06 #6
As many have stated it is ok to throw an exception in the constructor.
Having said that i would recommend against it. Over the years i have
found it helped me a lot better to just have constructors put the object
into a safe state. I do work that might throw exceptions in a different
method like Setup. I forget all the pains i had in the past that
eventually brought my to doing things this way because I just do it as a
matter of course now.

Leon Lambert

Sek wrote:
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 object.

TIA
Sek
Aug 1 '06 #7
I agree with what Lambert wrote. I have always tried to insure that
constructors simply put things into an "initialized" state. If you have to do
something more involved, and especially anything that might throw an
exception or have other failures, I always put them into a "Create" or "Open"
type of function. Yes, this can lead to other errors (i.e. forgetting to call
the appropriate Create function), but I just like it better because of all
the "magic" constructors that happen behind your back (copy constructors,
etc.).

"Leon Lambert" wrote:
As many have stated it is ok to throw an exception in the constructor.
Having said that i would recommend against it. Over the years i have
found it helped me a lot better to just have constructors put the object
into a safe state. I do work that might throw exceptions in a different
method like Setup. I forget all the pains i had in the past that
eventually brought my to doing things this way because I just do it as a
matter of course now.

Leon Lambert

Sek wrote:
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 object.

TIA
Sek
Aug 1 '06 #8
Leon Lambert wrote:
As many have stated it is ok to throw an exception in the constructor.
Having said that i would recommend against it. Over the years i have
found it helped me a lot better to just have constructors put the object
into a safe state. I do work that might throw exceptions in a different
method like Setup. I forget all the pains i had in the past that
eventually brought my to doing things this way because I just do it as a
matter of course now.
So how would you implement FileStream? If you don't do anything in the
constructor, it's just saving the exception for later on - where's the
advantage of that? Yes, the object would be in a "safe" state - but
it's useless until it's opened the file, and that's the point at which
you should throw an exception if the file can't be found, IMO.

Jon

Aug 1 '06 #9
Brian C. Barnes wrote:
I agree with what Lambert wrote. I have always tried to insure that
constructors simply put things into an "initialized" state. If you have to do
something more involved, and especially anything that might throw an
exception or have other failures, I always put them into a "Create" or "Open"
type of function. Yes, this can lead to other errors (i.e. forgetting to call
the appropriate Create function), but I just like it better because of all
the "magic" constructors that happen behind your back (copy constructors,
etc.).
C# doesn't *have* "magic" constructors though. I really don't see the
advantage of forcing the client to make two calls when one would do.
The *only* point I could see is that if you're implementing
IDisposable, you need to make sure that your constructor cleans up
after itself if it throws an exception after acquiring a resource. If
you do that in the Create method, you can assume that the client will
call Dispose appropriately.

However, using a Create/Initialize/etc method means that your object
isn't really *usable* when the constructor has returned, which is the
state I like to be in.

It's quite possible that throwing exceptions from constructors is a bad
idea in other environments, but I think it's fine in C#.

Jon

Aug 1 '06 #10
"chanmm" <ch*****@hotmail.comwrote:
Contructor supposed to handle simple tasks like initialization. If up to the
stage you need to throw exception from contructor
Interesting; the need to flag errors from constructors was one of the
motivations for introducing exceptions into C++, since return value
can't be used.

There's nothing wrong with throwing an exception from a constructor.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #11
"simida" <yo**********@gmail.comwrote:
As far as i know, It's not a appropriate way to throw exception from a
constructor.
A constructor should leave an object in a valid state. If the
constructor arguments do not give the right information to leave the
object in a valid state with all its invariants holding, then the
constructor should definitely throw an exception.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #12
Leon Lambert <la******@inil.comwrote:
As many have stated it is ok to throw an exception in the constructor.
Having said that i would recommend against it. Over the years i have
found it helped me a lot better to just have constructors put the object
into a safe state. I do work that might throw exceptions in a different
method like Setup. I forget all the pains i had in the past that
eventually brought my to doing things this way because I just do it as a
matter of course now.
I remember it being difficult to throw exceptions correctly in C++
constructors, but C# is not C++, and does not have many of its flaws.

There was never a problem in throwing exceptions in constructors Delphi
either, for a simple reason - Delphi initialized the object's fields to
all-zeros before running the constructor. In Delphi, when a constructor
threw an exception, the destructor was invoked. Because all the fields
were initialized to zero, it was trivial for the destructor to correctly
and safely destroy the partially-constructed object. The same is a lot
harder in C++ when one is doing heap allocation etc. in the constructor.

For similar reasons, in C# there's nothing wrong with throwing in the
constructor, and nor are there any complications or difficulties in the
mode of C++.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #13
Brian C. Barnes <bc******@newsgroups.nospamwrote:
I agree with what Lambert wrote. I have always tried to insure that
constructors simply put things into an "initialized" state. If you have to do
something more involved, and especially anything that might throw an
exception or have other failures, I always put them into a "Create" or "Open"
type of function. Yes, this can lead to other errors (i.e. forgetting to call
the appropriate Create function), but I just like it better because of all
the "magic" constructors that happen behind your back (copy constructors,
etc.).
What magic constructors in C#? I suspect you're projecting C++'s
language flaws on other object-oriented languages :)

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #14
Jon Skeet [C# MVP] wrote:
simida wrote:
>As far as i know, It's not a appropriate way to throw exception from
a constructor.

It's widely done, and there's no reason not to do it in .NET. In
unmanaged C++ there are reasons why it's a bad idea, but they don't
apply to .NET.
Excuse me? Indicating failure from a constructor is one of the primarly
reason that exceptions were added to the C++ language over a decade ago. It
is the proper way to signal failure from a constructor. Used together with
the RAII idiom (resource acquisition is initialization - as manifested in
smart pointers and tools like ScopeGuard), exceptions thrown from within a
constructor are safe and easy to use correctly. The alternative, multi-part
construction (via an "init" function), is an error-prone model than permits
partially constructed objects to exist - something that the .NET designers
felt so strongly about that they ensured that all objects are fully
constructed before the first statement of the constructor runs.

-cd
Aug 1 '06 #15
Barry Kelly wrote:
For similar reasons, in C# there's nothing wrong with throwing in the
constructor, and nor are there any complications or difficulties in
the mode of C++.
I'd really like to hear those "difficulties". It's quite normal to throw
exceptions from C++ constructors - it's the one of the main reasons that
exceptions were added to C++.

-cd
Aug 1 '06 #16
Carl Daniel [VC++ MVP] wrote:
It's widely done, and there's no reason not to do it in .NET. In
unmanaged C++ there are reasons why it's a bad idea, but they don't
apply to .NET.

Excuse me? Indicating failure from a constructor is one of the primarly
reason that exceptions were added to the C++ language over a decade ago. It
is the proper way to signal failure from a constructor.
I think I must have heard exaggerated claims of the problems involved.
I believe (after a quick search) that after an exception is thrown in a
C++ constructor that the destructor is not called, so resources need to
be cleaned up in that situation. I guess some people have taken that as
a reason not to throw exceptions at all in C++...

Jon

Aug 1 '06 #17
Sek,

There are some good comments here already. The Framework Design
Guidelines book says that it is acceptable to throw exceptions when
appropriate. But, it also recommends keeping constructor operations
simple. Often the only thing a constructor needs to do is capture the
parameters. As a result many constructors should only need to throw on
invalid parameters.

I *usually* avoid long running or complex operations in constructors
anyway because it's not clear to the caller that they're happening. If
it makes more sense to construct an object in conjunction with a
complex operation then I'll use a static factory method where I have
the liberty of giving it a clear name using appropriate verbage. If
you go with this approach (and I'm not suggesting that you do) then
you'd naturally be limiting the circumstances where exceptions are
thrown by constructors.

Brian
Sek wrote:
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 object.

TIA
Sek
Aug 1 '06 #18
But the whole point of .NET is that it is language egnostic - and the
libraries we write in C# may get used by C++/CLI projects, or other languages
that perhaps can't deal with exceptions in constructors as cleanly as C# can.
Since the author really doesn't know what language environment is being used,
I would tend to stick with the more pessimistic approach of doing as little
as possible in the constructor.
C# doesn't *have* "magic" constructors though. I really don't see the
advantage of forcing the client to make two calls when one would do.
The *only* point I could see is that if you're implementing
IDisposable, you need to make sure that your constructor cleans up
after itself if it throws an exception after acquiring a resource. If
you do that in the Create method, you can assume that the client will
call Dispose appropriately.
Aug 1 '06 #19
Brian C. Barnes <bc******@newsgroups.nospamwrote:
But the whole point of .NET is that it is language egnostic - and the
libraries we write in C# may get used by C++/CLI projects, or other languages
that perhaps can't deal with exceptions in constructors as cleanly as C# can.
Care to cite any examples? Any language which can't cope with
constructors throwing exceptions is in serious trouble when it comes to
using the framework classes.
Since the author really doesn't know what language environment is being used,
I would tend to stick with the more pessimistic approach of doing as little
as possible in the constructor.
My approach is to do what's appropriate in the constructor to create a
viable object. In the case of something like FileStream, that involves
opening the file - which would naturally involve throwing an exception
if the file cannot be opened.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 1 '06 #20
Jon wrote:
My approach is to do what's appropriate in the constructor to create a
viable object. In the case of something like FileStream, that involves
opening the file - which would naturally involve throwing an exception
if the file cannot be opened.
The FileStream constructor is another example of a poor design choice.
IMHO, opening a file is not a simple operation. There should be an
Open method (either instance or static) that performs this work. Even
after reading the documentation it's still not perfectly clear that the
constructor actually opens the file. But the deed has been done and
throwing exceptions is the only appropriate choice.

Brian

Aug 1 '06 #21
"Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospamwr ote:
Barry Kelly wrote:
For similar reasons, in C# there's nothing wrong with throwing in the
constructor, and nor are there any complications or difficulties in
the mode of C++.

I'd really like to hear those "difficulties". It's quite normal to throw
exceptions from C++ constructors - it's the one of the main reasons that
exceptions were added to C++.
I know - I mentioned it in a parallel post.

Consider (implementions inlined, copy constructors / assignment
operators / auto_ptr etc. all ignored, for the sake of exposition):

---8<---
class Foo
{
private:
Bar *m_bar;

public:
Foo(bool doThrow)
{
m_bar = new Bar;
if (doThrow)
throw 0;
}

~Foo()
{
delete m_bar;
}
};
--->8---

The same in Delphi:

---8<---
type
Foo = class
private
FBar: Bar;

public
constructor Create(doThrow: Boolean);
// inlined here for exposition, not actually valid Delphi syntax
begin
FBar = Bar.Create;
if doThrow then
throw Exception.Create;
end;

destructor Destroy; override;
begin
FBar.Free; // Free() checks for nil pointer first
end;

end;
--->8---

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #22
Brian Gideon <br*********@yahoo.comwrote:
Jon wrote:
My approach is to do what's appropriate in the constructor to create a
viable object. In the case of something like FileStream, that involves
opening the file - which would naturally involve throwing an exception
if the file cannot be opened.

The FileStream constructor is another example of a poor design choice.
IMHO, opening a file is not a simple operation. There should be an
Open method (either instance or static) that performs this work. Even
after reading the documentation it's still not perfectly clear that the
constructor actually opens the file. But the deed has been done and
throwing exceptions is the only appropriate choice.
Having a FileStream which hasn't opened the file seems pretty odd to me
- and would mean that you'd have extra code in everything which used
it. Having no public constructors, just static methods, would be doable
- but I don't see the advantage. From the client's point of view
there'd still be an exception occurring.

Where's the benefit in making the constructor *not* open the file? I'm
all for constructors only doing a sensible amount of work - but not
when that means that an object isn't actually ready for use until
another particular method has been called.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 1 '06 #23
"Brian Gideon" <br*********@yahoo.comwrote:
Jon wrote:
My approach is to do what's appropriate in the constructor to create a
viable object. In the case of something like FileStream, that involves
opening the file - which would naturally involve throwing an exception
if the file cannot be opened.

The FileStream constructor is another example of a poor design choice.
I strongly disagree!
IMHO, opening a file is not a simple operation. There should be an
Open method (either instance or static) that performs this work.
This would create a three-state stream - closed, open and disposed -
rather than what we currently have, two states - open and disposed. With
an 'Open' operation, one would expect to be able to close and open it
repeatedly. I, for one, prefer objects with simple purposes in life and
with a minimum of 'modality'.

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #24

Barry Kelly wrote:
The FileStream constructor is another example of a poor design choice.

I strongly disagree!
Well, it's definitely debatable. I can't honestly say that I even
completely agree with my own statement nor do I always follow the
"simple operation" rule for constructors myself. I just think there is
a better alternative in this case.
IMHO, opening a file is not a simple operation. There should be an
Open method (either instance or static) that performs this work.

This would create a three-state stream - closed, open and disposed -
rather than what we currently have, two states - open and disposed. With
an 'Open' operation, one would expect to be able to close and open it
repeatedly. I, for one, prefer objects with simple purposes in life and
with a minimum of 'modality'.
And you'd get just that with a static factory method; a method with a
verb name clearly describing what it is going to do.

Aug 1 '06 #25
Sek.. You can throw an exception in the constructor.. or use a static
class factory
and return null on failure.. or set a flag isValid to false.

Beware that the finalizer will be called in C# even on exceptional
construction!

http://www.geocities.com/Jeff_Louie/oop30.htm

C++ and PHP coders will be surprised to learn that in C# even if an
exception is
thrown in the user defined constructor, the user defined destructor will
still be
called.

Regards,
Jeff
>>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 object.<<

*** Sent via Developersdex http://www.developersdex.com ***
Aug 1 '06 #26
"Brian Gideon" <br*********@yahoo.comwrote:
Barry Kelly wrote:
The FileStream constructor is another example of a poor design choice.
I strongly disagree!

Well, it's definitely debatable. I can't honestly say that I even
completely agree with my own statement nor do I always follow the
"simple operation" rule for constructors myself. I just think there is
a better alternative in this case.
IMHO, opening a file is not a simple operation. There should be an
Open method (either instance or static) that performs this work.
This would create a three-state stream - closed, open and disposed -
rather than what we currently have, two states - open and disposed. With
an 'Open' operation, one would expect to be able to close and open it
repeatedly. I, for one, prefer objects with simple purposes in life and
with a minimum of 'modality'.

And you'd get just that with a static factory method; a method with a
verb name clearly describing what it is going to do.
One already has 'File.Open' and related methods which provide the
appropriate arguments to the FileStream constructor.

But on the other hand - what's the benefit from using this approach? If
one calls the static method rather than using the constructor, what's
been gained over the losses: extra complexity, the divorce between where
the object is constructed (the static method) and the actual object
implementation, and the extra mode on the file stream? Also, won't all
streams now need this Open() method? What do you do when you get a
stream from elsewhere, like a NetworkStream from a socket? Do you need
to open that too? If not, where does all this documentation go?

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #27
Jeff Louie <je********@yahoo.comwrote:
Sek.. You can throw an exception in the constructor.. or use a static
class factory
and return null on failure.. or set a flag isValid to false.

Beware that the finalizer will be called in C# even on exceptional
construction!

http://www.geocities.com/Jeff_Louie/oop30.htm

C++ and PHP coders will be surprised to learn that in C# even if an
exception is
thrown in the user defined constructor, the user defined destructor will
still be
called.
On the other hand, Delphi programmers won't be surprised - although
calling C# '~Class()' syntax a 'destructor' is, of course, an abuse of
terminology... :)

-- Barry

--
http://barrkel.blogspot.com/
Aug 1 '06 #28
Barry Kelly wrote:
One already has 'File.Open' and related methods which provide the
appropriate arguments to the FileStream constructor.

But on the other hand - what's the benefit from using this approach?
File.Open doesn't have an ambiguous meaning. It's perfectly clear from
the name that a file will be opened if no exceptions are thrown. The
problem is that it's on a separate class, which is fine, but how would
one know to look at the File class if they're currently interested in
the FileStream class. It makes more sense to add it to the FileStream
class as well. Consider the following lines of code.

FileStream stream = new FileStream("foo.txt");
FileStream stream = FileStream.Open("foo.txt");

Without knowing anything about a FileStream what can we say about these
lines of code? The only thing we can say for certain about the first
line is that stream can be used to read/write data in the foo.txt file.
We can say more about the second. Not only can it read/write to
foo.txt, but it is *ready* to do so since the method clearly indicates
that the stream is open when it's returned.

But, that's not why I think it was a poor design choice. I think it's
a poor design choice because a constructor that throws an IOException
has a complex operation embedded in it. That contradicts the following
guideline.

"Do minimal work in the constructor. Constructors should not do much
work other than to capture the constructor parameters. The cost of any
other processing should be delayed until required." --Framework Design
Guidelines by Cwalina & Abrams.
If
one calls the static method rather than using the constructor, what's
been gained over the losses: extra complexity, the divorce between where
the object is constructed (the static method) and the actual object
implementation, and the extra mode on the file stream?
I don't see where there's extra complexity. In fact, from the callers
perspective the interface would be more self describing and thus
simpler to use!

You wouldn't necessarily have to move logic around to accomodate the
factory method. Just make the constructor private and have the factory
call that if you like.

Using the static factory method approach it would still be impossible
to reopen a closed stream since there wouldn't be an instance method
there to do it.
Also, won't all
streams now need this Open() method?
Yep. That's how most of the objects that acquire resources in the
System.Net and System.Data namespaces work. Though, in those examples
they're usually instance methods.
What do you do when you get a
stream from elsewhere, like a NetworkStream from a socket? Do you need
to open that too? If not, where does all this documentation go?
I'd say no especially if the documentation on the stream indicated that
a caller can assume it's open if the Close method hasn't been
previously called. That's pretty much how it works now. The same
semantics can be acheived with a static factory method.

Aug 1 '06 #29
"Brian Gideon" <br*********@yahoo.comwrote:
Barry Kelly wrote:
One already has 'File.Open' and related methods which provide the
appropriate arguments to the FileStream constructor.

But on the other hand - what's the benefit from using this approach?

"Do minimal work in the constructor. Constructors should not do much
work other than to capture the constructor parameters. The cost of any
other processing should be delayed until required." --Framework Design
Guidelines by Cwalina & Abrams.
I agree with the general principle that constructors should not initiate
an operation that is costly in time or space, but I don't agree with the
notion that a constructor should delay 'full initialization with all
invariants holding' until a later 'Initialize' method is called. All
that does is complicate the interface, multiply the possible states,
etc. etc. I'm more interested in how you think the rationale behind the
guideline applies in this particular case.

Or to put it another way, I think there's a balance to be achieved -
described below.
If
one calls the static method rather than using the constructor, what's
been gained over the losses: extra complexity, the divorce between where
the object is constructed (the static method) and the actual object
implementation, and the extra mode on the file stream?

I don't see where there's extra complexity. In fact, from the callers
perspective the interface would be more self describing and thus
simpler to use!
I can only talk about my personal experience using different classes. I
personally find FileStream nice and easy to work with, and I like its
idiom. On the other hand, I find System.Diagnostics.Process far more
awkward. I need to construct an instance, fiddle with various properties
before finally invoking a method.

Now, starting a process etc. is an expensive operation. As such, it
shouldn't occur inside the constructor. What's more, the various
subtleties and options on how one can create a process aren't fully
appreciated by people who are new to the functionality. With respect to
creating a process, I think the static method approach along with a
do-very-little constructor and tweakable properties works well - though
the static methods are missing in the current version of the BCL.

Thus, I think it's a question of where one draws the line. I think that
FileStream is good and that making it a tweakable stillborn object until
you finally call 'Open()' would be overkill. Just MHO.

I think it has more to do with the cost of the operation than the fact
that it may or may not throw exceptions.
You wouldn't necessarily have to move logic around to accomodate the
factory method. Just make the constructor private and have the factory
call that if you like.

Using the static factory method approach it would still be impossible
to reopen a closed stream since there wouldn't be an instance method
there to do it.
This is more an argument for named constructors, but I think that's an
orthogonal topic to throwing exceptions from constructors.
Also, won't all
streams now need this Open() method?

Yep. That's how most of the objects that acquire resources in the
System.Net and System.Data namespaces work. Though, in those examples
they're usually instance methods.
But these objects typically block for lengthy time periods. I would
agree to a rule of thumb that says "any operation that you might
consider making asynchronous doesn't belong in a constructor".

-- Barry

--
http://barrkel.blogspot.com/
Aug 2 '06 #30
Barry Kelly <ba***********@gmail.comwrote:
FBar = Bar.Create;
if doThrow then
throw Exception.Create;
I've been programming in too many different languages lately. That
should be:

FBar := Bar.Create;
if doThrow then
raise Exception.Create('blah');

-- Barry

--
http://barrkel.blogspot.com/
Aug 2 '06 #31
Jon Skeet [C# MVP] wrote:
Carl Daniel [VC++ MVP] wrote:
>>It's widely done, and there's no reason not to do it in .NET. In
unmanaged C++ there are reasons why it's a bad idea, but they don't
apply to .NET.

Excuse me? Indicating failure from a constructor is one of the
primarly reason that exceptions were added to the C++ language over
a decade ago. It is the proper way to signal failure from a
constructor.

I think I must have heard exaggerated claims of the problems involved.
I believe (after a quick search) that after an exception is thrown in
a
C++ constructor that the destructor is not called, so resources need
to
be cleaned up in that situation. I guess some people have taken that
as
a reason not to throw exceptions at all in C++...
That's correct - the body of the destructor is not run, but the destructors
of all base classes and member variables are run (assuming the exception was
thrown from the body of the constructor). If you use the RAII pattern (as
all modern C++ programmers should), your constructor and destructor bodies
will almost always be empty and throwing an exception from the constructor
will do exactly what you'd want it to do.

-cd
Aug 2 '06 #32

Barry Kelly wrote:
<snip>
>
Consider (implementions inlined, copy constructors / assignment
operators / auto_ptr etc. all ignored, for the sake of exposition):

---8<---
class Foo
{
private:
Bar *m_bar;

public:
Foo(bool doThrow)
{
m_bar = new Bar;
if (doThrow)
throw 0;
}

~Foo()
{
delete m_bar;
}
};
--->8---
I think you're projecting your C# way of thinking onto C++, therefore
doing unwise design choices...

Why is the m_bar member allocated allocated on the heap? Any reason for
that in the 1st place ???? 9 times out of 10, the good solution is as
imple as :

class Foo
{
Bar m_bar; //no need for constructor nor destructor
};

Now, suppose there is a good reason to allocate m_bar on the heap, what
about doing modern C++, eg usig the RAII idiom ??

class Foo
{
std::auto_ptr<Barm_bar; //depending on context,
boost::shared_ptr may be another option

public:
Foo(bool doThrow)
: m_bar(new Bar())
{
if (doThrow)
throw 0;
}
};

Arnaud
MVP - VC

Aug 2 '06 #33
Jon wrote:
Brian Gideon <br*********@yahoo.comwrote:
Having a FileStream which hasn't opened the file seems pretty odd to me
- and would mean that you'd have extra code in everything which used
it. Having no public constructors, just static methods, would be doable
- but I don't see the advantage. From the client's point of view
there'd still be an exception occurring.

Where's the benefit in making the constructor *not* open the file? I'm
all for constructors only doing a sensible amount of work - but not
when that means that an object isn't actually ready for use until
another particular method has been called.
I realize I'm splitting hairs on this one, but the main advantage IMHO
is better compliance with the guideline. Anything that throws an
IOException can't possibly be a simple operation. If you use the
static factory method approach then you would have an object that's
ready to use in one call with the added benefit that the interface
should be easier to understand for the caller.

I think one advantage of the guideline is that it encourages developers
to put complex operations in methods where 1) they're expected and 2)
that have self describing names. To me anyway, line 2 is an order of
magnitude more clear that the stream is open than line 1.

FileStream stream = new FileStream("foo.txt"); // Line 1
FileStream stream = FileStream.Open("foo.txt"); // Line 2

I'm not saying that throwing exceptions from a constructor is bad. In
fact the same guidelines say it's acceptable when appropriate. Since
the FileStream does attempt to open a file then throwing an exception
is a logical choice.

Aug 2 '06 #34
ad******@club-internet.fr wrote:
Barry Kelly wrote:
<snip>

Consider (implementions inlined, copy constructors / assignment
operators / auto_ptr etc. all ignored, for the sake of exposition):

---8<---
class Foo
{
private:
Bar *m_bar;

public:
Foo(bool doThrow)
{
m_bar = new Bar;
if (doThrow)
throw 0;
}

~Foo()
{
delete m_bar;
}
};
--->8---

I think you're projecting your C# way of thinking onto C++, therefore
doing unwise design choices...

Why is the m_bar member allocated allocated on the heap?
That's irrelevant. This isn't a program, so there are no design choices.
There are only language features.
Now, suppose there is a good reason to allocate m_bar on the heap, what
about doing modern C++, eg usig the RAII idiom ??
I explicitly mentioned that I was ignoring auto_ptr for the sake of
exposition.

In my view, C++'s destructors along with the RAII pattern are basically
required to be overused in order to hack around a limitation in the
language. The RAII pattern works very well for simple scenarios (and
they should be used in such reusable scenarios), like an owned pointer
or a ref-counted pointer, but not every paired operation between
constructor and destructor is so reusable that it merits a new type.

-- Barry

--
http://barrkel.blogspot.com/
Aug 2 '06 #35
Brian Gideon <br*********@yahoo.comwrote:
Where's the benefit in making the constructor *not* open the file? I'm
all for constructors only doing a sensible amount of work - but not
when that means that an object isn't actually ready for use until
another particular method has been called.

I realize I'm splitting hairs on this one, but the main advantage IMHO
is better compliance with the guideline. Anything that throws an
IOException can't possibly be a simple operation. If you use the
static factory method approach then you would have an object that's
ready to use in one call with the added benefit that the interface
should be easier to understand for the caller.
To split hairs even further, I regard compliance with guidelines per se
as not being an advantage at all - it's only an advantage to the extent
that the guideline itself makes sense. Clearly I disagree with the
generality of the guideline in this case, so compliance with it is
irrelevant to me.
I think one advantage of the guideline is that it encourages developers
to put complex operations in methods where 1) they're expected and 2)
that have self describing names. To me anyway, line 2 is an order of
magnitude more clear that the stream is open than line 1.
*That* is much more of an argument I can at least understand. I still
disagree with it, largely because opening the stream on construction is
precisely the behaviour I expect, but at least it's a reasonable
argument :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Aug 2 '06 #36

"Barry Kelly" <ba***********@gmail.coma crit dans le message de news:
ac********************************@4ax.com...
ad******@club-internet.fr wrote:
In my view, C++'s destructors along with the RAII pattern are basically
required to be overused in order to hack around a limitation in the
language.
Which limitation? The limitation is rather on the .NET finalizer side IMHO :
since you don't know when they are run, there is almost nothing you can do
inside them!
The RAII pattern works very well for simple scenarios (and
they should be used in such reusable scenarios), like an owned pointer
or a ref-counted pointer, but not every paired operation between
constructor and destructor is so reusable that it merits a new type.
That's why there are generic solutions to the RAII idiom, such as ScopeGuard
(http://www.ddj.com/dept/cpp/184403758)

Arnaud
MVP - VC
Aug 3 '06 #37
"Arnaud Debaene" <ad******@club-internet.frwrote:
"Barry Kelly" <ba***********@gmail.coma crit dans le message de news:
ac********************************@4ax.com...
ad******@club-internet.fr wrote:
In my view, C++'s destructors along with the RAII pattern are basically
required to be overused in order to hack around a limitation in the
language.
Which limitation? The limitation is rather on the .NET finalizer side IMHO :
since you don't know when they are run, there is almost nothing you can do
inside them!
We'll have to agree to disagree - I think it's a limitation of the
language definition, nothing to do with .NET or otherwise, in the
context of "throwing an exception from the constructor".
The RAII pattern works very well for simple scenarios (and
they should be used in such reusable scenarios), like an owned pointer
or a ref-counted pointer, but not every paired operation between
constructor and destructor is so reusable that it merits a new type.

That's why there are generic solutions to the RAII idiom, such as ScopeGuard
(http://www.ddj.com/dept/cpp/184403758)
Yes, more hacks and crutches...

-- Barry

--
http://barrkel.blogspot.com/
Aug 4 '06 #38

"Barry Kelly" <ba***********@gmail.coma crit dans le message de news:
gf********************************@4ax.com...
"Arnaud Debaene" <ad******@club-internet.frwrote:
>"Barry Kelly" <ba***********@gmail.coma crit dans le message de news:
ac********************************@4ax.com...
ad******@club-internet.fr wrote:
In my view, C++'s destructors along with the RAII pattern are basically
required to be overused in order to hack around a limitation in the
language.
Which limitation? The limitation is rather on the .NET finalizer side
IMHO :
since you don't know when they are run, there is almost nothing you can
do
inside them!

We'll have to agree to disagree - I think it's a limitation of the
language definition, nothing to do with .NET or otherwise, in the
context of "throwing an exception from the constructor".
But which limitation are you talking about exactly? That's what I don't
understand...
The RAII pattern works very well for simple scenarios (and
they should be used in such reusable scenarios), like an owned pointer
or a ref-counted pointer, but not every paired operation between
constructor and destructor is so reusable that it merits a new type.

That's why there are generic solutions to the RAII idiom, such as
ScopeGuard
(http://www.ddj.com/dept/cpp/184403758)

Yes, more hacks and crutches...
Huuh? Andrei Alexdandrescu doing "hacks and crutchs" ??? Care to justify
your appreciation?

More seriously, I believe there is a true divergence ni philosophy here :
The C++ approach is "do as little as possible in language itself, and as
much as possible in libraries", whereas your approach (I am not really sure
this is indeed the C# approach) is "put everything in language and compiler
itself, so that there is nothing left to do in libraries". I believe the 1st
approach is more flexible because, first, it makes it much easier to replace
a defective component....

Arnaud
MVP - VC
Aug 4 '06 #39
"Arnaud Debaene" <ad******@club-internet.frwrote:
"Barry Kelly" <ba***********@gmail.coma crit dans le message de news:
gf********************************@4ax.com...
We'll have to agree to disagree - I think it's a limitation of the
language definition, nothing to do with .NET or otherwise, in the
context of "throwing an exception from the constructor".

But which limitation are you talking about exactly? That's what I don't
understand...
Like I said, we'll have to agree to disagree.
More seriously, I believe there is a true divergence ni philosophy here :
The C++ approach is "do as little as possible in language itself, and as
much as possible in libraries",
Nonsense! If that were true, the language would look like LISP! :P
whereas your approach (I am not really sure
this is indeed the C# approach) is "put everything in language and compiler
itself, so that there is nothing left to do in libraries".
That's clearly not true, because there seem to be substantial libraries
packaged with the .NET framework. :) Even the C# basic types are defined
in a library!

You'll have to forgive me, I'm being quite facetious, at the end of a
long day.
I believe the 1st
approach is more flexible because, first, it makes it much easier to replace
a defective component....
Consider std::stack::pop() - C++ is a language in which you can't even
write an exception-safe mutator method which returns a value of a
user-defined type!

I think a programming language should have a carefully selected set of
abstractions and abstraction creation tools that are suitable for the
domain to which it is applied. I think C++ has a set of useful
abstractions and abstraction creation tools, but there are interactions
between some of them that are less than desirable - and that the
resulting sum is somewhat less than the sum of its parts. I think it
would be a better language if it removed some features, and changed some
functionality - but then it would no longer be C++.

-- Barry

--
http://barrkel.blogspot.com/
Aug 4 '06 #40
Barry Kelly wrote:
"Do minimal work in the constructor. Constructors should not do much
work other than to capture the constructor parameters. The cost of any
other processing should be delayed until required." --Framework Design
Guidelines by Cwalina & Abrams.

I agree with the general principle that constructors should not initiate
an operation that is costly in time or space, but I don't agree with the
notion that a constructor should delay 'full initialization with all
invariants holding' until a later 'Initialize' method is called. All
that does is complicate the interface, multiply the possible states,
etc. etc. I'm more interested in how you think the rationale behind the
guideline applies in this particular case.
My rationale is based on the fact that some FileStream constructors
acquire a resource in a complex manner. To me, opening a file, which
may require network activity, does not qualify as "minimal work".
Or to put it another way, I think there's a balance to be achieved -
described below.
There's always a balance. That's why I can't honestly say I'm too hung
up about it. There are other interface design problems in the BCL that
are more significant. And it's certainly possible that I'm
interpreting the guideline too strictly. But, it did come from people
who are smarter than I so I want to be cautious about ignoring it
altogether.
I can only talk about my personal experience using different classes. I
personally find FileStream nice and easy to work with, and I like its
idiom. On the other hand, I find System.Diagnostics.Process far more
awkward. I need to construct an instance, fiddle with various properties
before finally invoking a method.

Now, starting a process etc. is an expensive operation. As such, it
shouldn't occur inside the constructor. What's more, the various
subtleties and options on how one can create a process aren't fully
appreciated by people who are new to the functionality. With respect to
creating a process, I think the static method approach along with a
do-very-little constructor and tweakable properties works well - though
the static methods are missing in the current version of the BCL.

Thus, I think it's a question of where one draws the line. I think that
FileStream is good and that making it a tweakable stillborn object until
you finally call 'Open()' would be overkill. Just MHO.
I don't know. Even if Open were an instance method I'm not sure it
would seem overkill to me. Afterall, that's how a lot (most?) of the
classes in the BCL work. But, you're right, as it is, the FileStream
class works well.
I think it has more to do with the cost of the operation than the fact
that it may or may not throw exceptions.
Yeah, I mean the exceptions that a constructor throws should have
little impact on how the guideline is followed. I just think opening a
file is a potentially expensive and complex operation.
This is more an argument for named constructors, but I think that's an
orthogonal topic to throwing exceptions from constructors.
You're right. We could probably start a whole thread on that topic.
But these objects typically block for lengthy time periods. I would
agree to a rule of thumb that says "any operation that you might
consider making asynchronous doesn't belong in a constructor".
It's probably a bit too specific to include in any formal
documentation. But, it does sound reasonable to me.

Aug 4 '06 #41

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Pierre Rouleau | last post by:
The std::exception class defined in the Standard C++ <exception> header specifies that the constructors could throw any exception becuase they do not have a throw() specification. Why is that? ...
3
by: Scott Brady Drummonds | last post by:
Hi, all, I've a fairly small piece of code that is causing me problems. I'm using std::string and am building a string of several dozen characters using several of std::string's functions: a...
40
by: Kevin Yu | last post by:
is it a bad programming design to throw exception in the try block then catch it??
5
by: KJ | last post by:
This is kind of hard to explain but I have a The controls are created with CreateChildControls(). Now let say I click a button and an error occurs in the control. If I throw it up it goes back...
10
by: mttc | last post by:
I read articles that suggest preventing delete by throwing Exception from RowDeleting Event. I not understand where I can catch this Error?
11
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...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, youll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shllpp 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.