开发者

Why is the C++ std::exception::what member const?

I'm curious as to why the std::exception::what member function is const?

class exception 
{
public:
  exception() throw() { }
  virtual ~exception() throw();

  /** Returns a C-style character string describing the general caus开发者_开发技巧e
   *  of the current error.  */
  virtual const char* what() const throw();
};


Calling the what() member function should not modify the observable state of the exception object.

Typically, exceptions are caught by const reference. For example,

try {
    // ...
}
catch (const std::exception& ex) {
    std::cout << ex.what();
}

If the what() member function was not const-qualified, this pattern wouldn't work because you wouldn't be able to call it from within the catch block.

If you don't want to generate the string to be returned from what() until it is called, you can materialize the string into a mutable member variable.


Because it doesn't mutate the Exception instance.

In general, all functions that do not mutate their class instance should be declared const, so that they can be called on const-qualified variables.


Flip the question. Why would it not be const?

If it was "char *what() const", you could modify the internal char array that what() is returning a pointer to. It'd be astoundingly stupid for exception() to allow arbitrary code to manipulate its internal buffers in that way, so what() returns a const char *, instead of a char *.

And if it was "const char *what()", without the const qualifier, it would indicate that calling what() would modify the internal state of the exception. Which it doesn't, and which you'd not expect it to do.

So we have what we have, "const char *what() const". A const function returning a pointer to a const array. And the result is that you can call it on a const reference. Which exceptions generally are.

After all, you don't usually change exceptions, you construct them, throw them, and then have the handling code manipulate them without changing them. So their member functions should be const.


The reasoning probably came from a desire to uphold stability. For example, an exception could be thrown if a process runs out of memory. If that is the case, it would be counter productive to modify "What" so that it might need more space. If the programmer attempted that, under those circumstances, it would immediately abort the whole program. Probably not what you intended.

Likewise, it is not appropriate for the What to use extra space from the stack - since that is precisely what is uwinding during a thrown exception.

That said, the boost library has a boost::exception that does allow you to add material to it as the exception propogates upward. Caveat Emptor.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜