473,396 Members | 1,866 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,396 software developers and data experts.

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

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

Sep 27 '07 #1
12 1887
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
Sep 27 '07 #2
On Sep 28, 7:30 pm, "Chris ( Val )" <chris...@gmail.comwrote:
On Sep 28, 7:03 pm, James Kanze <james.ka...@gmail.comwrote:
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

Sep 28 '07 #3
On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <ch******@gmail.comsaid:
>
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)

Sep 28 '07 #4
On Sep 28, 10:52 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <chris...@gmail.comsaid:


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

Sep 28 '07 #5
Chris ( Val ) wrote:
On Sep 28, 10:52 pm, Pete Becker <p...@versatilecoding.comwrote:
>On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <chris...@gmail.com>
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
Sep 28 '07 #6
On Sep 29, 12:35 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Chris ( Val ) wrote:
[snip]
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?
Yes.
In my book you cannot use any partially constructed object except to
take its address.
Thats fine, but I thought there may be a chance that the
object could be stopped in its tracs, and somehow completed.

But having a re-think about it doesn't seem possible, well
at least I couldn't find any supporting material without
spending hours digging deep into the standard :-)
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.
Thanks again,
Chris Val

Sep 28 '07 #7
On 2007-09-28 10:33:00 -0400, "Chris ( Val )" <ch******@gmail.comsaid:
>
What I am curious about is at what point does the object actually
cease to exist? (which scope?)
Well, formally, it never existed, because its constructor didn't run to
completion. Mechanically, what happens is that when the exception
escapes from the try block (or, more generally, when an exception
escapes from a constructor), the destructors for the various subobjects
that have been constructed are run. In addition, if the object was
being created with new, the compiler calls the corresponding operator
delete to release the memory. It's up to the compiler to get all that
logic right.

struct OK
{
~OK() { std::cout << "destroying an OK object\n"; }
};

struct Throws
{
Throws { throw 1; }
};

struct Complicated: OK, Throws, OK
{
~Complicated() { std::cout << "destroying a Complicated object\n"; }
};

Your compiler might warn you that you can't call members of OK, because
their names are ambiguous. Ignore that: it's not relevant here.

Try creating an object of type Complicated. (I haven't compiled this
code, but it ought to be more or less okay).

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

Sep 28 '07 #8
On 2007-09-28 10:54:39 -0400, Pete Becker <pe**@versatilecoding.comsaid:
On 2007-09-28 10:33:00 -0400, "Chris ( Val )" <ch******@gmail.comsaid:
>>
What I am curious about is at what point does the object actually
cease to exist? (which scope?)

Well, formally, it never existed, because its constructor didn't run to
completion. Mechanically, what happens is that when the exception
escapes from the try block
Sorry, I suspect that should be "from the catch clause". I'm a bit
pressed for time this morning, so I haven't looked it up.

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

Sep 28 '07 #9
On Sep 28, 11:30 am, "Chris ( Val )" <chris...@gmail.comwrote:
On Sep 28, 7:03 pm, James Kanze <james.ka...@gmail.comwrote:
[...]
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.
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();
This is undefined behavior, since it accesses an uninitialized
pointer. If you get here, the assign in the try block has never
occured (and there is no Base object).
delete B;
}
std::cin.get();
return 0;
}
I am interested to hear your, and the groups
thoughts on the validity of such a construct.
Totally invalide.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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

Sep 28 '07 #10
On Sep 28, 4:33 pm, "Chris ( Val )" <chris...@gmail.comwrote:
On Sep 28, 10:52 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2007-09-28 05:30:31 -0400, "Chris ( Val )" <chris...@gmail.comsaid:
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.
Could you show it. If you replace the line with new Base...,
with something like:

Base b( "Oracle.driver.bar" ) ;

then b isn't even in scope in the catch block, and cannot be
accessd.
What I am curious about is at what point does the object actually
cease to exist? (which scope?)
Which object. The object whose destructor exits via an
exception never begins to exist, so the question of when it
ceases to exist is moot.
Is it not possible for it to even be partially constucted to
report such information back?
No. Or rather, it can put information in the exception, which
will propagate up. But if a constructor exits because of an
exception, all fully constructed sub-objects are immediately
destructed, and if the constructor was called as part of a new
expression, the allocated memory is immediately freed.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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

Sep 28 '07 #11
On Sep 29, 8:38 am, James Kanze <james.ka...@gmail.comwrote:
On Sep 28, 11:30 am, "Chris ( Val )" <chris...@gmail.comwrote:
On Sep 28, 7:03 pm, James Kanze <james.ka...@gmail.comwrote:

[...]


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.
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();

This is undefined behavior, since it accesses an uninitialized
pointer. If you get here, the assign in the try block has never
occured (and there is no Base object).
delete B;
}
std::cin.get();
return 0;
}
I am interested to hear your, and the groups
thoughts on the validity of such a construct.

Totally invalide.
The non-pointer version that I spoke of was
totally wrong. I thought about it after I
posted, amd realised I was just assigning
a new object in the catch block. It was late
and I totally confused myself :-)

Thanks to both you and Peter for clarifying it.

Cheers,
Chris Val

Sep 29 '07 #12
On Sep 29, 12:57 am, Pete Becker <p...@versatilecoding.comwrote:
On 2007-09-28 10:54:39 -0400, Pete Becker <p...@versatilecoding.comsaid:
On 2007-09-28 10:33:00 -0400, "Chris ( Val )" <chris...@gmail.comsaid:
What I am curious about is at what point does the object actually
cease to exist? (which scope?)
Well, formally, it never existed, because its constructor didn't run to
completion. Mechanically, what happens is that when the exception
escapes from the try block

Sorry, I suspect that should be "from the catch clause". I'm a bit
pressed for time this morning, so I haven't looked it up.
No problem at all, I appreciate the help and example.

Thanks,
Chris Val


Sep 29 '07 #13

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

Similar topics

5
by: Hubert Hermanutz | last post by:
Hi, as yet i have readed in the MSDN about exception handling. The only references that i was founded, described try, catch, finally and throw objects. But I am searching about an occation to...
7
by: Tiraman | last post by:
Hi , I am using allot the try catch in my code and the question is if it is good ? it will decrease my performance ? one more question
9
by: Michael MacDonald | last post by:
Does someone have a good site I can visit or explain the use of Try" and Catch foe exception/error handling. What is the logic behind this command and maybe an example would be great!!!! Mike_Mac...
7
by: Sean Kirkpatrick | last post by:
I got caught with my pants down the other day when trying to explain Try...Catch...Finally and things didn't work as I had assumed. Perhaps someone can explain to me the purpose of Finally. I've...
4
by: chris | last post by:
Hi, I write some code guarded with exception handling... simplified code look like this... int main(int argc, char* argv){ try{
13
by: Alison Givens | last post by:
....... that nobody knows the answer. I can't imagine that I am the only one that uses parameters in CR. So, my question again: I have the following problem. (VB.NET 2003 with CR) I have a...
28
by: RickHodder | last post by:
I'm getting frustrated with using try...catch with local variables: The code below wont compile in .NET 1.1: I get the following error: "Use of unassigned local variable 'oProcessFileReader' " ...
8
by: reuce-google | last post by:
Hi folks, I want to store an exception and rethrow it later: CException m_pEc = NULL; // Class variable. try { throw new CMemoryException(); }
28
by: gnuist006 | last post by:
I have some code like this: (if (test) (exit) (do something)) or (if (test)
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.