I think that the first const shows that you're returning a char* which will be const
That is correct. The what()
member function returns a value of type const char *
, which is a pointer to constant characters. This is exactly like a value returned from any other function. If you are not sure how to read type declarations involving pointers and const-specifiers, you should study up.
I think ... the second const is to ensure the object invoked (MyException) is not changed.
That is also correct. When a const
specifier comes at the end of a member function's signature, it specifies that the member function operates on const
instances of that type. In other words, this is legal:
const MyException myex;
std::cout << myex.what() << std::endl;
Whereas if const
had been omitted from the what()
function signature, the above code would have been illegal. myex
would have had to have been non-const.
Generally, member functions that do not mutate the state of an object should be marked const
to promote writing const-correct code.
Not sure on the throw().
This is a C++03-style exception specifier. The empty throw()
is a guarantee that the function does not throw any exceptions. It is not a function call. The reason it is parenthesized is because it takes possible exceptions as arguments. For example, throw(int)
means that the function might throw an exception of type int
(which should never be thrown, but this is just an example).
The new C++11 style would be an annotation with noexcept
. This is what you should generally prefer to use when writing modern C++ code, as others have
commented. Note that it doesn't use the parenthesized syntax anymore. This is because it was broadly agreed that dynamic exception specifications are useless, except in the very special case of indicating that a function does not throw at all.
Googling "exception specification c++" will return lots of relevant information.
Also is there a difference between using a struct and a class to create your own exception?
No, it does not matter. struct
and class
are identical in C++ except for the default access modifier. That is, by default, all members of a struct
are public
, whereas all members of a class
are private
by default.
In C++, the struct
keyword really just defines a class
. Now, semantically, I and others like to use struct
for POD types and class
for everything else, but this isn't something that is enforced by the language. You can use either one interchangeably (except on certain versions of MSVC, where it will issue warnings when it sees two different declarations of a class, one that uses struct
and the other that uses class
; this is, however, a nonsense warning and you can safely ignore or suppress it).