派生自std :: exception的类的赋值运算符

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了派生自std :: exception的类的赋值运算符相关的知识,希望对你有一定的参考价值。

我从std::runtime_error派生了一个自定义异常类>

静态分析器警告我,如果我定义或删除默认操作(复制ctor,复制/移动运算符,析构函数等。,则应全部定义或删除它们。

为了解决这个愚蠢的警告,我写了丢失的赋值运算符,但是随后又收到另一个警告,即我的运算符隐藏了基本的非虚拟赋值运算符!

由于基类具有私有成员,我无法复制它,看来唯一的解决方案是直接为基对象部分调用基赋值运算符,然后复制其余的*this对象并最终返回*this

但是在此之前,我先看了基本operator=的功能以及它的外观:

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;
;

现在知道这是我的实现(带有注释),用于调用基本分配并复制其余的派生对象:

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;
;

这是这样做的正确方法吗?我认为这看起来很麻烦,但我不确定。

编辑

这里是完整的类,以供参考:

#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

我从std :: runtime_error静态分析器派生了一个自定义异常类,警告我,如果我定义或删除默认操作(复制ctor,复制/移动运算符,析构函数等。,我...

答案

感谢Ulrich Eckhardt,Peter和其他人的好评,这是我的工作方式,结果完全没有警告:

class Exception : public std::runtime_error

public:
    ~Exception() noexcept;  // can't be inlined in release build (defaulted in source)

    // default/delete
    Exception(const Exception&) = default;
    Exception(Exception&&) = default;
    Exception& operator=(const Exception&) noexcept = default;
    Exception& operator=(Exception&&) noexcept(false) = deault;

    // the rest of the code ...
;

以上是关于派生自std :: exception的类的赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章

C++:当包含从类模板派生的类的标头时,编译器警告 C4505

序列化派生自DynamicObject类的类的实例

将派生自基类的类的实例传递给函数

自定义 __repr__ 作为从 Enum 派生的类的类方法

C++ 包含两个派生自同一个基类的类

python中的异常类的认识理解?