Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing custom exceptions in C++ [closed]

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?

like image 968
lorefnon Avatar asked Nov 06 '12 20:11

lorefnon


People also ask

Should I create custom exceptions?

You should only implement a custom exception if it provides a benefit compared to Java's standard exceptions. The class name of your exception should end with Exception. If an API method specifies an exception, the exception class becomes part of the API, and you need to document it.

Can you throw exceptions in C?

C doesn't support exceptions. You can try compiling your C code as C++ with Visual Studio or G++ and see if it'll compile as-is. Most C applications will compile as C++ without major changes, and you can then use the try... catch syntax.

How do you handle custom exceptions?

Basically, Java custom exceptions are used to customize the exception according to user need. Consider the example 1 in which InvalidAgeException class extends the Exception class. Using the custom exception, we can have your own exception and message. Here, we have passed a string to the constructor of superclass i.e.


2 Answers

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).

like image 129
jamesdlin Avatar answered Oct 04 '22 04:10

jamesdlin


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

like image 44
Peter Wildemann Avatar answered Oct 04 '22 02:10

Peter Wildemann