By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,987 Members | 1,607 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,987 IT Pros & Developers. It's quick & easy.

exceptions

P: n/a
Hello. Here I am again trying to understand the examples of a C++
tutorial. When compiling the original source code:

// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const
char* what()
{
return "My exception happened";
}
} myex;

int main () {
try
{
throw myex;
}
catch (exception& e)
{
cout << e.what() << endl;
}
return 0;
}

I get this:

11myexception

which obviously is not the desired answer. I modified slightly the
code, just writing as type of the argument of the "catch" function the
derived class (myexception) , instead the "parent" one (exception) in
which case I am forced to declare the object function "what" as
public (reason for the difference with respect to the former case ???):
// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const

public:
char* what()
{
return "My exception happened";
}
} myex;

int main () {
try
{
throw myex;
}
catch (myexception& e)
{
cout << e.what() << endl;
}
return 0;
}

Now I get the right answer:

My exception happened

Can someone explain to me the reason of this. I would rather expect
that the type of the parent class could be used for the argument of the
calling function . Or not?

regards

Sep 21 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Josefo wrote:
Hello. Here I am again trying to understand the examples of a C++
tutorial. When compiling the original source code:

// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const
char* what()
This does not override the function in std::exception because you
changed the signature. Delete the line above and uncomment the line
above that, and then you need only to make it public (cf.
http://www.parashift.com/c++-faq-lit...html#faq-21.1).
{
return "My exception happened";
}
} myex;
Don't create an instance here. Create it where you throw.
>
int main () {
try
{
throw myex;
throw myexception();
}
catch (exception& e)
Prefer to catch by const reference:

catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}

I get this:

11myexception

which obviously is not the desired answer. I modified slightly the
code, just writing as type of the argument of the "catch" function the
derived class (myexception) , instead the "parent" one (exception) in
which case I am forced to declare the object function "what" as
public (reason for the difference with respect to the former case ???):
// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const

public:
char* what()
{
return "My exception happened";
}
} myex;

int main () {
try
{
throw myex;
}
catch (myexception& e)
{
cout << e.what() << endl;
}
return 0;
}

Now I get the right answer:

My exception happened

Can someone explain to me the reason of this. I would rather expect
that the type of the parent class could be used for the argument of the
calling function . Or not?
You can (and often should) use the parent class to catch. Just fix your
exception class as I describe above.

Cheers! --M

Sep 21 '06 #2

P: n/a
mlimber wrote:
Josefo wrote:
Hello. Here I am again trying to understand the examples of a C++
tutorial. When compiling the original source code:

// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const
char* what()

This does not override the function in std::exception because you
changed the signature.
Hello. Can you explain me what do you mean by "changing signature"?.
>Delete the line above and uncomment the line
above that, and then you need only to make it public (cf.
http://www.parashift.com/c++-faq-lit...html#faq-21.1).
. I did it. It does not yet work. I should eliminate the last "const"
in the line to be uncommented (on the other hand it has no meaning and
should be an error, am I right?).
About the need to make it public: there is a public inheritance from
exception to myexception, therefore all public members of the base
class should be also public for the derived one, right? So, why should
I declare as public the "what" member function which supposedly is
public (or not?) in the base class?.
{
return "My exception happened";
}

} myex;

Don't create an instance here. Create it where you throw.

int main () {
try
{
throw myex;

throw myexception();
}
catch (exception& e)

Prefer to catch by const reference:

catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
>
You can (and often should) use the parent class to catch. Just fix your
exception class as I describe above.

Cheers! --M
I tried to do as uou suggest, but with no results. By the way, as far
as I know (very little, evidently..) the "virtual" word should only be
used when the declaration of the virtual function is made in the base
class, not when defined in a derived class declaration. right? In fact,
when I leave it it makes no difference (apparently, at least), it gives
no error at compilation but the result is the same ( the output is:
11myexception)

Here is the code:

// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const
public:
const char* what()

// char* what()
{
return "My exception happened";
}
//} myex;
};

int main () {
try
{
// throw myex;
throw myexception();

}
// catch (exception& e)
catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}

Cheers
Josefo

Sep 22 '06 #3

P: n/a
Josefo wrote:
mlimber wrote:
Josefo wrote:
Hello. Here I am again trying to understand the examples of a C++
tutorial. When compiling the original source code:
>
// standard exceptions
#include <iostream>
#include <exception>
using namespace std;
>
class myexception: public exception
{
// virtual const char* what() const
char* what()
This does not override the function in std::exception because you
changed the signature.

Hello. Can you explain me what do you mean by "changing signature"?.
The signature of the what function in std::exception is:

virtual const char* what() const

but the signature of your function is different:

char* what()

Virtual is optional in your override, but the consts are not.
Delete the line above and uncomment the line
above that, and then you need only to make it public (cf.
http://www.parashift.com/c++-faq-lit...html#faq-21.1).

. I did it. It does not yet work.
User error, methinks. This code works for me:

#include <iostream>
#include <exception>
using namespace std;

class myexception : public exception
{
public:
virtual const char* what() const
{
return "My exception happened";
}
};

int main()
{
try
{
throw myexception();
}
catch( const exception& e )
{
cout << e.what() << endl;
}
return 0;
}
I should eliminate the last "const"
in the line to be uncommented (on the other hand it has no meaning and
should be an error, am I right?).
No. See
<http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.10>.
About the need to make it public: there is a public inheritance from
exception to myexception, therefore all public members of the base
class should be also public for the derived one, right? So, why should
I declare as public the "what" member function which supposedly is
public (or not?) in the base class?.
Because you are *changing* its access. This is permissible but evil.
See
<http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.1>.
{
return "My exception happened";
}
} myex;
Don't create an instance here. Create it where you throw.
>
int main () {
try
{
throw myex;
throw myexception();
}
catch (exception& e)
Prefer to catch by const reference:

catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}

You can (and often should) use the parent class to catch. Just fix your
exception class as I describe above.

Cheers! --M

I tried to do as uou suggest, but with no results. By the way, as far
as I know (very little, evidently..) the "virtual" word should only be
used when the declaration of the virtual function is made in the base
class, not when defined in a derived class declaration. right? In fact,
when I leave it it makes no difference (apparently, at least), it gives
no error at compilation but the result is the same ( the output is:
11myexception)
The virtual keyword is optional. Personally, I prefer to put it in
derived classes to remind me that the function in question is
overriding a function from a base class.
Here is the code:

// standard exceptions
#include <iostream>
#include <exception>
using namespace std;

class myexception: public exception
{
// virtual const char* what() const
public:
const char* what()
Without making this a const member function (that's what the const at
the end does), you have unintentionally created a const overload (see
<http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.12>)
that does not replace std::exception::what().

It's like if you did this:

struct Base
{
virtual void f( int ) { /*...*/ }
};

struct Derived : Base
{
virtual void f( double ) { /*...*/ }
};

Derived has not actually override f(int) because you changed the
function signature. So...

void Foo( Base& pb, Derived& pd )
{
pb.f( 1 ); // ok: calls Base::f(int)
pd.f( 1 ); // ok: calls Base::f(int)

pb.f( 1.1 ); // compile-time error!
pd.f( 1.1 ); // ok: calls Derived::f(double)
}

Cheers! --M

Sep 22 '06 #4

P: n/a
Hello:
mlimber wrote:
>This code works for me:

#include <iostream>
#include <exception>
using namespace std;

class myexception : public exception
{
public:
virtual const char* what() const
{
return "My exception happened";
}
};

int main()
{
try
{
throw myexception();
}
catch( const exception& e )
{
cout << e.what() << endl;
}
return 0;
}
But not for me. I get this run-time errors:

josemanuel@josefo:~/C++/C++_Language_Tutorial$ c++
standard_exception_mlimber_good.c
standard_exception_mlimber_good.c:8: error: especificador throw más
flexible para 'virtual const char* myexception::what() const'
/usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/exception:61:
error: sustituyendo 'virtual const char* std::exception::what()
const throw ()'
(By the way, trivial spanish-to-english translation:
especificador mas flexible para ...............more flexible specifier
for
substituyendo..................................sub stituting
)
I am running this versionof the compiler:

josemanuel@josefo:~/C++/C++_Language_Tutorial$ c++ -v
Usando especificaciones internas.
Objetivo: i486-linux-gnu
Configurado con: ../src/configure -v
--enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr
--enable-shared --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix --enable-nls
--program-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu
--enable-libstdcxx-debug --enable-java-awt=gtk-default
--enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre
--enable-mpfr --disable-werror --with-tune=pentium4
--enable-checking=release i486-linux-gnu
Modelo de hilos: posix
gcc versión 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
(translation:
usando especificaciones internas.......using internal specifications
Configurando...configuring
modelo de hilos....model of threads)

Some hint? Cheers

Josefo

Sep 22 '06 #5

P: n/a
Josefo wrote:
Hello:
mlimber wrote:
This code works for me:

#include <iostream>
#include <exception>
using namespace std;

class myexception : public exception
{
public:
virtual const char* what() const
{
return "My exception happened";
}
};

int main()
{
try
{
throw myexception();
}
catch( const exception& e )
{
cout << e.what() << endl;
}
return 0;
}

But not for me. I get this run-time errors:

josemanuel@josefo:~/C++/C++_Language_Tutorial$ c++
standard_exception_mlimber_good.c
standard_exception_mlimber_good.c:8: error: especificador throw más
flexible para 'virtual const char* myexception::what() const'
/usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/exception:61:
error: sustituyendo 'virtual const char* std::exception::what()
const throw ()'
(By the way, trivial spanish-to-english translation:
especificador mas flexible para ...............more flexible specifier
for
substituyendo..................................sub stituting
)
I am running this versionof the compiler:

josemanuel@josefo:~/C++/C++_Language_Tutorial$ c++ -v
Usando especificaciones internas.
Objetivo: i486-linux-gnu
Configurado con: ../src/configure -v
--enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr
--enable-shared --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix --enable-nls
--program-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu
--enable-libstdcxx-debug --enable-java-awt=gtk-default
--enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre
--enable-mpfr --disable-werror --with-tune=pentium4
--enable-checking=release i486-linux-gnu
Modelo de hilos: posix
gcc versión 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
(translation:
usando especificaciones internas.......using internal specifications
Configurando...configuring
modelo de hilos....model of threads)

Some hint? Cheers
Looks like your std::exception::what() has a no-throw specification.
Make your overload read:

virtual const char* what() const throw()
{ ... }

Cheers! --M

Sep 22 '06 #6

P: n/a
mlimber wrote:
Looks like your std::exception::what() has a no-throw specification.
Make your overload read:

virtual const char* what() const throw()
{ ... }

Cheers! --M
Thanks, you are right. And finally...how may I override the no- throw
specification when the exception is launched directly? (without the
"throw myexception", which prevents me to override the no-throw
specification when declaring the derived class "myexception"). For
instance:

// bad_alloc standard exception
#include <iostream>
#include <exception>
using namespace std;

int main () {
try
{
int* myarray= new int[1000000000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}

I get ( thanks to you, now I undestand why, but I do not know how to
solve it):

josemanuel@josefo:~/C++/C++_Language_Tutorial$ ./a.out
Standard exception: St9bad_alloc
Cheers

Josefo

Sep 22 '06 #7

P: n/a
Josefo wrote:
mlimber wrote:
Looks like your std::exception::what() has a no-throw specification.
Make your overload read:

virtual const char* what() const throw()
{ ... }

Cheers! --M

Thanks, you are right. And finally...how may I override the no- throw
specification when the exception is launched directly? (without the
"throw myexception", which prevents me to override the no-throw
specification when declaring the derived class "myexception"). For
instance:
I think you mean "indirectly" since in the example below "new"
generates the exception ("directly" would be an explicit throw
statement on your part as in the previous posts).
// bad_alloc standard exception
#include <iostream>
#include <exception>
using namespace std;

int main () {
try
{
int* myarray= new int[1000000000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}

I get ( thanks to you, now I undestand why, but I do not know how to
solve it):

josemanuel@josefo:~/C++/C++_Language_Tutorial$ ./a.out
Standard exception: St9bad_alloc
I don't understand what the problem is. You get a std::bad_alloc
exception, which is just what you should get if new fails. What were
you expecting?

Cheers! --M

Sep 22 '06 #8

P: n/a
Josefo wrote:
mlimber wrote:
>Looks like your std::exception::what() has a no-throw specification.
Make your overload read:

virtual const char* what() const throw()
{ ... }

Cheers! --M

Thanks, you are right. And finally...how may I override the no- throw
specification when the exception is launched directly? (without the
"throw myexception", which prevents me to override the no-throw
specification when declaring the derived class "myexception"). For
instance:
I think you're confused. the no throw specification means that what()
is guaranteed not to throw.

Sep 23 '06 #9

P: n/a
In article <jY***************@newssvr11.news.prodigy.com>,
no*****@here.dude says...

[ ... ]
I think you're confused. the no throw specification means that what()
is guaranteed not to throw.
Not really. It really means if it throws anything, unexpected() will be
called (and by default, unexpected() will call terminate()). Therefore,
what() can throw, but nothing can catch whatever it throws. The user can
use set_unexpected to change the default behavior, but the unexpected
handler cannot return -- it can only exit by throwing another exception
that is allowed by the original exception specification. Since that list
is empty in this case, you can't do a whole lot else in the unexpected
exception handler either...

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 23 '06 #10

P: n/a
mlimber wrote:
>
I think you mean "indirectly" since in the example below "new"
generates the exception ("directly" would be an explicit throw
statement on your part as in the previous posts).
You are right. I'm sorry, I was messing the things.
>
// bad_alloc standard exception
#include <iostream>
#include <exception>
using namespace std;

int main () {
try
{
int* myarray= new int[1000000000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
return 0;
}

I get ( thanks to you, now I undestand why, but I do not know how to
solve it):

josemanuel@josefo:~/C++/C++_Language_Tutorial$ ./a.out
Standard exception: St9bad_alloc

I don't understand what the problem is. You get a std::bad_alloc
exception, which is just what you should get if new fails. What were
you expecting?
Right. Thanks a lot to all of you.

Cheers.

Josefo

Sep 23 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.