I derived a custom exception class from std::runtime_error
static analyzer is giving me a warning that if I define or delete default operation (copy ctors, copy/move operators, destructors etc..), I should define or delete them all.
to resolve this silly warning, I wrote the missing assignment operator but then I got another warning that now my operator hides the base non virtual assignment operator!
Since base class has private members which I cant copy it looks like the only solution is to invoke base asignment operator directly for base object part and the copy the rest of *this
object and finaly return *this
but before doing that I took a look on what the base operator=
does and here what it looks like:
exception& operator=(exception const& _Other) noexcept
{
if (this == &_Other)
{
return *this;
}
__std_exception_destroy(&_Data);
__std_exception_copy(&_Other._Data, &_Data);
return *this;
}
private:
__std_exception_data _Data;
};
Now knowing that Here is my implementation (with comments) to invoke base asignment and the copy the rest of the derived object:
class Exception :
public std::runtime_error
{
public:
// ...
Exception& operator=(const Exception& other)
{
if (this == &other)
{
return *this;
}
// first copy only base class data to *this
*dynamic_cast<std::runtime_error*>(this) =
runtime_error::operator=(
*dynamic_cast<std::runtime_error*>(
const_cast<Exception*>(&other)));
// then copy derived class data to *this
mInfo = other.mInfo;
mCode = other.mCode;
// finally return complete copy
return *this;
}
private:
std::error_code mCode;
std::string mInfo;
};
Is this correct way to do this? I think this looks like trouble but I'm not sure.
EDIT
here is complete class, for reference:
#pragma warning (disable : 4275) // base needs to have DLL interface
class ERROR_API Exception :
public std::runtime_error
{
public:
~Exception() noexcept; // cant be inlined in release build
// default/delete
Exception(const Exception&) = default;
Exception(Exception&&) = delete;
Exception& operator=(const Exception& other)
{
if (this == &other)
{
return *this;
}
// copy base class data to *this
*dynamic_cast<std::runtime_error*>(this) =
runtime_error::operator=(
*dynamic_cast<std::runtime_error*>(
const_cast<Exception*>(&other)));
// copy derived class data to *this
mInfo = other.mInfo;
mCode = other.mCode;
return *this;
}
Exception& operator=(Exception&&) = delete;
/** Construct from error enum */
template<typename Enum>
Exception(Enum err_enum);
/** Construct from error enum and string*/
template<typename Enum>
Exception(Enum err_enum, String message);
/** Construct from error_code object */
inline Exception(std::error_code err_code);
/** Construct from error_code object and string */
inline Exception(std::error_code err_code, String message);
/** Get error_condidtion name */
inline virtual std::string ConditionName() const;
/** Get error_category name */
inline virtual std::string CategoryName() const;
/** Get error_condition value */
inline virtual int ConditionValue() const noexcept;
/** Get error_condition value */
inline virtual int ErrorValue() const noexcept;
/** Get additional information string passed to constructor */
inline virtual const String& GetInfo() const noexcept;
/** Get error_code object associated with this exception object */
inline virtual const std::error_code& code() const noexcept;
private:
SUPPRESS(4251); // member needs to have DLL interface
std::error_code mCode;
SUPPRESS(4251); // member needs to have DLL interface
String mInfo;
};
#pragma warning (default : 4275) // base needs to have DLL interface
Thanks to great comments from Ulrich Eckhardt, Peter and others here is how I made it work, result is no warning at all:
class Exception : public std::runtime_error
{
public:
~Exception() noexcept; // can't be inlined in release build (defaulted in source)
// default/delete
Exception(const Exception&) noexcept = default;
Exception(Exception&&) noexcept = default;
Exception& operator=(const Exception&) noexcept = default;
Exception& operator=(Exception&&) noexcept(false) = deault;
// the rest of the code ...
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.