Pergunta

I am coming from a Ruby and Java background and have recently begun exploring C++.

While my initial attempts at creating custom exceptions by simply subclassing exception class failed with obscure, I found the following example posted on a site:

class Exception : public exception
{
public:
  Exception(string m="exception!") : msg(m) {}
  ~Exception() throw() {}
  const char* what() const throw() { return msg.c_str(); }

private:
  string msg;
};

My understanding of semantics of C++ is not very mature at the moment, and I would like to have a better understanding of what is going on here.

In the statement const char* what() const throw() what does the part const throw() do, and what kind of programming construct is it?

Also, what is the purpose and intent of throw() in the destructor specification ~Exception() and why do I need to have a destructor specification although I don't need it do something in particular? Shouldn't the destructor inherited from exception be sufficient?

Foi útil?

Solução

const after a method declares that the method does not mutate the object. (There are exceptions, and generally it's used to mean "does not mutate the object in an externally-visible way.)

The throw() after the method declaration is an exception specification; it's similar to the throws E1, E2 exception specifications that you see in Java. However, in C++, exception specifications are not checked at compilation-time and are generally considered to be mostly useless (they are now deprecated). throw() is the only somewhat useful form, meaning that the function declares that it must not throw an exception (and if it does, it's a logical error, and the program will invoke an unexpected exception handler, by default terminating the program).

The destructor is explicitly declared because if left unspecified, the compiler will generate a destructor that invokes the base class destructor, and the compiler-generated destructor will not use a throw() exception specification (despite the fact that throwing exceptions in destructors is never a good idea).

Outras dicas

You are currently dealing with some style things of C++! So when you want to actually have an exception-object you may use std::exception, which is explained here on cppreference.

But since you could throw and catch everything in C++, you may even define your own exception class or use more basic aspects, e.g.

try  {
    throw("S0M3, M4YB3 CR1PT1C STR1NG!");  
} catch(char const* exceptStr) {  
    SomeFuncThatDecodesTheString(exceptStr); 
}

Your other topics are more a kind of personal style or standard:

  • An empty destructor like ~FooClass() {} is only there two show "I really do nothing!". Sometimes they might also be useful, when you use a strict system for writing your classes (e.g. First the public space, including the standard ctor at first and the standard dtor as the second function ...) to kind of force you (or some other coder) to write into the existing braces/function and therefore not desroying your holy order :)
  • You may write a throw() behind classes for insurance to other people, that the class does only throw exceptions of the types stated in the parantheses. Therefore a function void FooFunc() throw(int,char) should only throw ints and chars. And an empty throw() is just to actually say "Hey coder, I do not throw anything!". You will often find this in the C++ standard library, since you are (mostly) only able to look at the prototypes and not the source. BTW the throw(someType(s)) might be a lie. The function may throw any other type or simply nothing! But don't be a liar, when you use this ;)

EDIT:

I wanted to add, that noexcept can (since C++11) also be used to declare an function, not to throw any exception. This is pretty more comprehensible than throw().

LG ntor

throw() in the destructor specification means that the destructor doesn't throw exceptions. Destructors in C++ should not throw exceptions - here is why.

Destructors in C++ are not inherited. If you don't write your own destructor then compiler will automatically generate a destructor for you. That destructor will call destructor of a base class if such class exists.

const specifier in Exception::what() declaration means that this method may be called for constant objects of type Exception. throw() specifier means the same as for the destructor.

You should get a book about C++, those are very basic questions.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top