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