Could anyone explain to me this definition of standard exception in C++:
virtual const char* what() const throw();
What does const throw()
mean at the end?
Could anyone explain to me this definition of standard exception in C++:
virtual const char* what() const throw();
What does const throw()
mean at the end?
These are two separate, unrelated, things.
The const
means that the member function won't modify any (non-mutable
) member variables; this in turn means that it can be called on const
objects. e.g.:
class Foo {
public:
void a() const {
x = 5; // Compiler error!
}
void b() {
x = 5; // This is fine
}
private:
int x;
};
int main() {
Foo p;
const Foo q;
p.a(); // This is fine
p.b(); // This is fine
q.a(); // This is fine
q.b(); // Compiler error!
}
The throw()
is an exception specifier. It declares that this function will not throw an exception. See e.g. Should I use an exception specifier in C++? for a discussion.
The const
means that the function will not change any members of the class it is embedded in, throw()
is an exception specification; the function promises not to throw an exception.
Note that since C++11 the exception specification throw
is deprecated because of several reasons: exception lists were too hard to maintain while throw(...)
was to non-expressive, so that throw()
was basically the only specification used anyway, and these specification were dynamically checked at runtime, producing a large overhead and thus slowing down your application.
Now, you can safely replace throw()
with noexcept(true)
, or just noexcept
. There will be no checks whether such a method actually throws an exception - it's a guarantee you give to the compiler, not vice versa. If an exception is thrown, std::terminate
is called.
These are separate issues.
const
From the standard (if too long, only read the bold parts):
Nonstatic member functions
[...] A non-static member function may be declared const, volatile, or const volatile. These cv-qualifiers affect the type of the this pointer (9.3.2). They also affect the function type (8.3.5) of the member function; a member function declared const is a const member function, a member function declared volatile is a volatile member function and a member function declared const volatile is a const volatile member function. [...]
The
this
pointer[...] In a const member function, the object for which the function is called is accessed through a const access path; therefore, a const member function shall not modify the object and its non-static data members. [...]
Storage class specifiers
[...] The mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const (7.1.6.1).
Summary: A member function qualified with const
is not allowed to change any member that is not declared mutable
. The reason for mutable
is that even if an object is const
, mechanism like caching can be done; it is good practice that the observable behavior of an object does not change by calling const member function.
throw()
Exception specifications [expect.spec]
A function declaration lists exceptions that its function might directly or indirectly throw by using an exception-specification as a suffix of its declarator.
More specifically, it is a dynamic-exception-specification, and a
[...] function is said to allow an exception of type E if its dynamic-exception-specification contains a type T for which a handler of type T would be a match (15.3) for an exception of type E.
In other words, the types within (
and )
are the exceptions that this function might throw. However, it is common practice to not use non-empty dynamic exception specifications for some good reasons.
Using throw()
, i.e. an empty exception list, in pre-C++11 was accepted practice to annotate functions that never throw. However, as of C++11, the current standard, one should use noexcept
instead.
Also, as of C++11,
[ Note: The use of dynamic-exception-specifications is deprecated (see Annex D). —end note ]
so use noexcept
instead.