Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Is it possible to catch an exception raised by a member variable?

Reply
Thread Tools

Is it possible to catch an exception raised by a member variable?

 
 
Angus
Guest
Posts: n/a
 
      09-27-2007
Hello

I have a class I am using which raises an exception in its constructor
if certain things aren't in place. I can easily create the situation
where an exception is raised.

If I use the create a member variable in a class using this class then
how do I catch the exception?

For now I have defined a member function as a pointer and in my
constructor in my class using the class which raises the exception, I
do a try catch block and do a new object. That works. But is it
possible to do a similar thing using a member variable?

Angus

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      09-27-2007
Angus wrote:
> I have a class I am using which raises an exception in its constructor
> if certain things aren't in place. I can easily create the situation
> where an exception is raised.


OK. So creation of a subobject fails. Quite common.

> If I use the create a member variable in a class using this class then
> how do I catch the exception?


The exception has to be caught by the code that instantiates (or rather
tries to instantiate) the host object.

> For now I have defined a member function as a pointer and in my
> constructor in my class using the class which raises the exception, I
> do a try catch block and do a new object. That works. But is it
> possible to do a similar thing using a member variable?


Yes, but if your member fails to be constructed, can your object still
exist and function? If it can, you should use the pointer solution,
which apparently works. If your object cannot exist and function with
some part of it missing, then you should do nothing, the constructor
of the entire object will throw (because some part of it throws), and
the exception has to be caught outside.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Chris ( Val )
Guest
Posts: n/a
 
      09-27-2007
On Sep 28, 2:22 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
> Angus wrote:
> > I have a class I am using which raises an exception in its constructor
> > if certain things aren't in place. I can easily create the situation
> > where an exception is raised.

>
> OK. So creation of a subobject fails. Quite common.
>
> > If I use the create a member variable in a class using this class then
> > how do I catch the exception?

>
> The exception has to be caught by the code that instantiates (or rather
> tries to instantiate) the host object.
>
> > For now I have defined a member function as a pointer and in my
> > constructor in my class using the class which raises the exception, I
> > do a try catch block and do a new object. That works. But is it
> > possible to do a similar thing using a member variable?

>
> Yes, but if your member fails to be constructed, can your object still
> exist and function? If it can, you should use the pointer solution,
> which apparently works. If your object cannot exist and function with
> some part of it missing, then you should do nothing, the constructor
> of the entire object will throw (because some part of it throws), and
> the exception has to be caught outside.


Hi Victor, I think it can still be created and exist under certain
circumstances:

For example:

You could use a function try block, which will then catch the
exception
in the initialiser list, prior to executing the body of the
constructor,
therefore the object is still alive to an extent, as it is still in
the
process of being created.

The try block itself becomes the constructor body, with the catch
block
immediately following it. A function try block also allows us to throw
out of the constructor with a different exception object than what was
initially caught.

Cheers,
Chris Val

 
Reply With Quote
 
Jonathan Lane
Guest
Posts: n/a
 
      09-28-2007
On Sep 27, 7:12 pm, "Chris ( Val )" <(E-Mail Removed)> wrote:
> On Sep 28, 2:22 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
>
>
>
> > Angus wrote:
> > > I have a class I am using which raises an exception in its constructor
> > > if certain things aren't in place. I can easily create the situation
> > > where an exception is raised.

>
> > OK. So creation of a subobject fails. Quite common.

>
> > > If I use the create a member variable in a class using this class then
> > > how do I catch the exception?

>
> > The exception has to be caught by the code that instantiates (or rather
> > tries to instantiate) the host object.

>
> > > For now I have defined a member function as a pointer and in my
> > > constructor in my class using the class which raises the exception, I
> > > do a try catch block and do a new object. That works. But is it
> > > possible to do a similar thing using a member variable?

>
> > Yes, but if your member fails to be constructed, can your object still
> > exist and function? If it can, you should use the pointer solution,
> > which apparently works. If your object cannot exist and function with
> > some part of it missing, then you should do nothing, the constructor
> > of the entire object will throw (because some part of it throws), and
> > the exception has to be caught outside.

>
> Hi Victor, I think it can still be created and exist under certain
> circumstances:
>
> For example:
>
> You could use a function try block, which will then catch the
> exception
> in the initialiser list, prior to executing the body of the
> constructor,
> therefore the object is still alive to an extent, as it is still in
> the
> process of being created.
>
> The try block itself becomes the constructor body, with the catch
> block
> immediately following it. A function try block also allows us to throw
> out of the constructor with a different exception object than what was
> initially caught.
>
> Cheers,
> Chris Val


I think the problem with this is that yes you can use the function
catch block but what can you do if it throws. The object doesn't exist
until it has completely finished construction. If you want to be able
to use the object without this member then it needs to be a pointer
with a try catch around it in the constructor body. That way you can
complete the constructor and just not use that member.
If you leave it as a non-pointer then all you can achieve in the
function catch is to translate the exception. The object still doesn't
exist because the constructor didn't complete. The stack will unwind
and the bits that were already constructed will be destructed. i.e.
it's a non object and can't be used.

Depends on what the poster wants to be able to do if a sub object
fails to construct. Of course, I may be mistaken I'm a bit foggy on
the whole functional try/catch stuff, it doesn't come up often for me.

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-28-2007
On Sep 27, 8:12 pm, "Chris ( Val )" <(E-Mail Removed)> wrote:
> On Sep 28, 2:22 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
> > Angus wrote:
> > > I have a class I am using which raises an exception in its constructor
> > > if certain things aren't in place. I can easily create the situation
> > > where an exception is raised.


> > OK. So creation of a subobject fails. Quite common.


> > > If I use the create a member variable in a class using this class then
> > > how do I catch the exception?


> > The exception has to be caught by the code that instantiates (or rather
> > tries to instantiate) the host object.


> > > For now I have defined a member function as a pointer and in my
> > > constructor in my class using the class which raises the exception, I
> > > do a try catch block and do a new object. That works. But is it
> > > possible to do a similar thing using a member variable?


> > Yes, but if your member fails to be constructed, can your object still
> > exist and function? If it can, you should use the pointer solution,
> > which apparently works. If your object cannot exist and function with
> > some part of it missing, then you should do nothing, the constructor
> > of the entire object will throw (because some part of it throws), and
> > the exception has to be caught outside.


> I think it can still be created and exist under certain
> circumstances:


Not if the construction of a sub-object fails.

> For example:


> You could use a function try block, which will then catch the
> exception in the initialiser list, prior to executing the body
> of the constructor, therefore the object is still alive to an
> extent, as it is still in the process of being created.


> The try block itself becomes the constructor body, with the
> catch block immediately following it. A function try block
> also allows us to throw out of the constructor with a
> different exception object than what was initially caught.


But you still don't have an object. You can use function try
blocks to remap the exception, or to treat it as a fatal error
(e.g. by calling abort or exit), but you cannot return normally
from the constructor, and the object that was being constructed
will not exist.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
Chris ( Val )
Guest
Posts: n/a
 
      09-28-2007
On Sep 28, 7:03 pm, James Kanze <(E-Mail Removed)> wrote:
> On Sep 27, 8:12 pm, "Chris ( Val )" <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On Sep 28, 2:22 am, "Victor Bazarov" <(E-Mail Removed)> wrote:
> > > Angus wrote:
> > > > I have a class I am using which raises an exception in its constructor
> > > > if certain things aren't in place. I can easily create the situation
> > > > where an exception is raised.
> > > OK. So creation of a subobject fails. Quite common.
> > > > If I use the create a member variable in a class using this class then
> > > > how do I catch the exception?
> > > The exception has to be caught by the code that instantiates (or rather
> > > tries to instantiate) the host object.
> > > > For now I have defined a member function as a pointer and in my
> > > > constructor in my class using the class which raises the exception, I
> > > > do a try catch block and do a new object. That works. But is it
> > > > possible to do a similar thing using a member variable?
> > > Yes, but if your member fails to be constructed, can your object still
> > > exist and function? If it can, you should use the pointer solution,
> > > which apparently works. If your object cannot exist and function with
> > > some part of it missing, then you should do nothing, the constructor
> > > of the entire object will throw (because some part of it throws), and
> > > the exception has to be caught outside.

> > I think it can still be created and exist under certain
> > circumstances:

>
> Not if the construction of a sub-object fails.
>
> > For example:
> > You could use a function try block, which will then catch the
> > exception in the initialiser list, prior to executing the body
> > of the constructor, therefore the object is still alive to an
> > extent, as it is still in the process of being created.
> > The try block itself becomes the constructor body, with the
> > catch block immediately following it. A function try block
> > also allows us to throw out of the constructor with a
> > different exception object than what was initially caught.

>
> But you still don't have an object. You can use function try
> blocks to remap the exception, or to treat it as a fatal error
> (e.g. by calling abort or exit), but you cannot return normally
> from the constructor, and the object that was being constructed
> will not exist.


Hi James,

I have produced a crude example that will attempt to
prove otherwise:

# include <iostream>
# include <string>
# include <exception>

struct DataSource {
DataSource( std::string ds )
{
if( ds != "Oracle.driver.foo" )
throw "Could not connect to database";
}
};

class Base
{
private:
DataSource Ds;
public:
Base( std::string );
~Base() { std::cout << "Destructing now...\n"; }
void Print()
{ std::cout << "I am still alive - Please try again.\n"; }
};

Base::Base( std::string ds )
try // function-try block
: Ds( ds ) {}
catch( const char* msg ) {
std::cout << "Exception Caught: \"" << msg << "\"" << '\n';
throw std::exception();
}

int main()
{
Base* B;

try {
B = new Base( "Oracle.driver.bar" );
}
catch( const std::exception& e )
{
B->Print();
delete B;
}

std::cin.get();
return 0;
}

I am interested to hear your, and the groups
thoughts on the validity of such a construct.



Cheers,
Chris Val

 
Reply With Quote
 
Chris ( Val )
Guest
Posts: n/a
 
      09-28-2007
On Sep 28, 7:30 pm, "Chris ( Val )" <(E-Mail Removed)> wrote:
> On Sep 28, 7:03 pm, James Kanze <(E-Mail Removed)> wrote:


Oh, I forgot to post the output - Here it is:

Exception Caught: "Could not connect to database"
I am still alive - Please try again.
Destructing now...

Cheers,
Chris Val

 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      09-28-2007
On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <(E-Mail Removed)> said:

>
> int main()
> {
> Base* B;
>
> try {
> B = new Base( "Oracle.driver.bar" );
> }
> catch( const std::exception& e )
> {
> B->Print();
> delete B;
> }
>
> std::cin.get();
> return 0;
> }
>
> I am interested to hear your, and the groups
> thoughts on the validity of such a construct.
>


It really doesn't show anything. Replace the "B = new ..." with "throw
std::exception();" and you'll probably get the same result. Calling
member functions on uninitialized pointers produces undefined behavior,
so anything you see is as valid as anything else.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

 
Reply With Quote
 
Chris ( Val )
Guest
Posts: n/a
 
      09-28-2007
On Sep 28, 10:52 pm, Pete Becker <(E-Mail Removed)> wrote:
> On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <(E-Mail Removed)> said:
>
>
>
>
>
>
>
> > int main()
> > {
> > Base* B;

>
> > try {
> > B = new Base( "Oracle.driver.bar" );
> > }
> > catch( const std::exception& e )
> > {
> > B->Print();
> > delete B;
> > }

>
> > std::cin.get();
> > return 0;
> > }

>
> > I am interested to hear your, and the groups
> > thoughts on the validity of such a construct.

>
> It really doesn't show anything. Replace the "B = new ..." with "throw
> std::exception();" and you'll probably get the same result. Calling
> member functions on uninitialized pointers produces undefined behavior,
> so anything you see is as valid as anything else.


I tried a non pointer version, and the results are the same.

What I am curious about is at what point does the object actually
cease to exist? (which scope?)

Is it not possible for it to even be partially constucted to
report such information back?

I know UB can mean anything can happen, but I'm curious.
Its a powerful drug that UB, it can get you hooked line
and sinker

Thanks for the feedback,
Chris Val

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-28-2007
Chris ( Val ) wrote:
> On Sep 28, 10:52 pm, Pete Becker <(E-Mail Removed)> wrote:
>> On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <(E-Mail Removed)>
>> said:
>>
>>
>>
>>
>>
>>
>>
>>> int main()
>>> {
>>> Base* B;

>>
>>> try {
>>> B = new Base( "Oracle.driver.bar" );
>>> }
>>> catch( const std::exception& e )
>>> {
>>> B->Print();
>>> delete B;
>>> }

>>
>>> std::cin.get();
>>> return 0;
>>> }

>>
>>> I am interested to hear your, and the groups
>>> thoughts on the validity of such a construct.

>>
>> It really doesn't show anything. Replace the "B = new ..." with
>> "throw std::exception();" and you'll probably get the same result.
>> Calling member functions on uninitialized pointers produces
>> undefined behavior, so anything you see is as valid as anything else.

>
> I tried a non pointer version, and the results are the same.
>
> What I am curious about is at what point does the object actually
> cease to exist? (which scope?)


The pointer does not cease to exist. The object, however, is not
created. So, whatever address the pointer contains in the 'catch'
block, is not the address of a valid object. That makes the pointer
_invalid_.

> Is it not possible for it to even be partially constucted to
> report such information back?


Partially constructed means not fully constructed, doesn't it? In
my book you cannot use any partially constructed object except to
take its address.

> I know UB can mean anything can happen, but I'm curious.
> Its a powerful drug that UB, it can get you hooked line
> and sinker


Yep.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
catch doesn't catch a thrown exception Marteno Rodia Java 5 08-05-2009 03:30 AM
exception raised for valid variable declaration? Carlos ASP .Net 1 02-17-2005 08:26 PM
Exception feature creep! (was: re-entering in the normal flow after an exception is raised) Lonnie Princehouse Python 8 10-02-2004 09:16 PM
Re: Catch event raised in a user control in parent page Karl ASP .Net 1 08-28-2004 01:01 PM
why catch (...) can not catch such exception John Black C++ 8 08-20-2004 02:34 PM



Advertisments