Josefo wrote:
Quote:
mlimber wrote:
Quote:
Josefo wrote:
Quote:
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.
Quote:
>
. 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;
}
Quote:
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>.
Quote:
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>.
Quote:
Quote:
Quote:
{
return "My exception happened";
}
Don't create an instance here. Create it where you throw.
Quote:
>
int main () {
try
{
throw myex;
throw myexception();
Quote:
}
catch (exception& e)
Prefer to catch by const reference:
catch (const exception& e)
Quote:
{
cout << e.what() << endl;
}
return 0;
}
>
Quote:
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.
Quote:
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