Is it good or bad practice to make pure virtual functions noexcept? I always thought we should not put extra restriction on its implementation classes that their implementation should be no throw since putting this may result in modification in implementation and unnecessary try catch blocks to prevent exception escape. i thought implementation should decide whether function can marked as noexcept not the exception specification should decide implementation?
Can some one please correct me if i am wrong here?
That noexcept keyword is tricky, but just know that if you use it, your coding world will spin faster.
There are two good reasons for the use of noexcept: First, an exception specifier documents the behaviour of the function. If a function is specified as noexcept, it can be safely used in a non-throwing function. Second, it is an optimisation opportunity for the compiler.
When an exception is thrown from a function that is declared noexcept or noexcept(true) , std::terminate is invoked. When an exception is thrown from a function declared as throw() in /std:c++14 mode, the result is undefined behavior. No specific function is invoked.
A pure virtual function makes it so the base class can not be instantiated, and the derived classes are forced to define these functions before they can be instantiated. This helps ensure the derived classes do not forget to redefine functions that the base class was expecting them to.
noexcept
is part of member function specification, in the same way as its return type, parameter list, and const
qualifier. It is there to help users of the function - obviously, at the expense of function's implementers.
If you need to give implementers more flexibility while providing your users with a noexcept
function, make a pair of functions - a non-virtual public function with noexcept
, and a protected virtual function without noexcept
. Make the public noexcept
function call virtual implementation, and handle exceptions to hide them from its callers:
class Base {
protected:
virtual void doSomethingImpl() = 0;
public:
void doSomething() noexcept {
try {
doSomethingImpl();
} catch(...) {
// Provide some handling here
}
}
};
class Derived : public Base {
void doSomethingImpl() {
... // Implementers have flexibility to throw here
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With