Bootstrap

c++ 20 语法规范, vs2019 类 exception 的定义,在 vcruntime_exception .h

这个源头文件,在 STL 模板库里的其他模板的定义中,会引用到,因此,记录与注释一下。源代码很短,直接展开来,同时也附上资源 .h 文件:

//
// vcruntime_exception.h
//
//      Copyright (c) Microsoft Corporation. All rights reserved.
//
// <exception> functionality that is implemented in the VCRuntime.
//

#pragma once

#include <eh.h>

#ifdef _M_CEE_PURE
    #include <vcruntime_new.h>
#endif

#if _VCRT_COMPILER_PREPROCESSOR && _HAS_EXCEPTIONS

#pragma warning(push)
//在栈中保存当前的警告状态
#pragma warning(disable: _VCRUNTIME_DISABLED_WARNINGS)

#pragma pack(push, _CRT_PACKING)
//保存原先的对齐状态,并重置为 8 字节对齐


_CRT_BEGIN_C_HEADER   // 在 cPP 里定义 c 代码

_VCRTIMP void __cdecl __std_exception_copy  // 这像是一个函数的声明, 功能是字符串复制
(   _In_  __std_exception_data const* _From,  _Out_ __std_exception_data* _To ); 

// 这像是一个函数的声明,功能像是销毁堆区的字符串
void __cdecl __std_exception_destroy( _Inout_ __std_exception_data* _Data );

// 此数据结构,作为下面的类 exception 的数据成员, _DoFree 初始化为 True
struct __std_exception_data { char const* _What;    bool _DoFree; };

_CRT_END_C_HEADER


namespace std  // 类 exception 定义于标准命名空间 std 
{ 
#pragma warning(push)  // 保存原先的警告状态
#pragma warning(disable: 4577)   // 'noexcept' used with no exception handling mode specified
class exception
{
private:
    __std_exception_data _Data; // 此数据成员的定义在上面
public:
    exception() noexcept : _Data() { } // 默认的空初始化
    
    virtual ~exception() noexcept {  __std_exception_destroy(&_Data);  } // 父类的虚析构函数

    explicit exception(char const* const _Message) noexcept : _Data() // 禁止隐式类型转换
    {
        __std_exception_data _InitData = { _Message, true };
        __std_exception_copy(&_InitData, &_Data);
    }

    exception(char const* const _Message, int) noexcept  : _Data() { _Data._What = _Message; }
    //构造函数的多个版本,重载。  copy 构造函数
    exception(exception const& _Other) noexcept : _Data()
    {
        __std_exception_copy(&_Other._Data, &_Data);
    }

    exception& operator=(exception const& _Other) noexcept // copy 赋值运算符函数
    {
        if (this == &_Other)       
            return *this;
        
        __std_exception_destroy(&_Data); // 先销毁自己原来保存的字符串
        __std_exception_copy(&_Other._Data, &_Data);
        return *this;
    }

    _NODISCARD virtual char const* what() const // 父类的虚成员函数,返回本类里保存的字符串的地址
    {
        return _Data._What ? _Data._What : "Unknown exception";
    }

};

class bad_exception : public exception // 定义 exception 的子类
{
public:
    bad_exception() noexcept : exception("bad exception", 1) {    }
};

class bad_alloc : public exception     // 定义 exception 的子类
{
public:
    bad_alloc() noexcept : exception("bad allocation", 1) {   }

private:
    friend class bad_array_new_length; // 友元类

    bad_alloc(char const* const _Message) noexcept : exception(_Message, 1) {  } //私有的有参构造函数
};

class bad_array_new_length : public bad_alloc // 孙子类
{
public:
    bad_array_new_length() noexcept : bad_alloc("bad array new length")  {  }
};

#pragma warning(pop) // 恢复原来的警告等级

} // namespace std

#pragma pack(pop) // 恢复原来的对齐方式

#pragma warning(pop) // _VCRUNTIME_DISABLED_WARNINGS
#endif // _VCRT_COMPILER_PREPROCESSOR && _HAS_EXCEPTIONS

谢谢

;