C++ 使用“static_cast”向下转换空指针(单继承或多继承)

C++ 使用“static_cast”向下转换空指针(单继承或多继承),c++,pointers,polymorphism,downcast,C++,Pointers,Polymorphism,Downcast,正如标题所说,如果我将指针强制转换为基类或派生类,当指针为null时,从C++11/C++14标准的角度来看,这是一个安全的操作吗 struct base { virtual ~base() = default; }; struct derived : base {}; struct wrapper { using allowed_derived_t = derived; base* base_ptr = nullptr; void set_ptr(base* pt

正如标题所说,如果我将指针强制转换为基类或派生类,当指针为null时,从C++11/C++14标准的角度来看,这是一个安全的操作吗

struct base
{
   virtual ~base() = default;
};

struct derived : base {};

struct wrapper
{
   using allowed_derived_t = derived;
   base* base_ptr = nullptr;

   void set_ptr(base* ptr)
   {
       if (!dynamic_cast<allowed_derived_t*>(ptr))
          throw std::logic_error("Check your user code");

      base_ptr = ptr;
   }

   allowed_derived_t* ptr() const
   { return static_cast<allowed_derived_t*>(base_ptr); }
};
struct base
{
virtual~base()=默认值;
};
派生结构:基{};
结构包装器
{
使用允许的\u派生\u t=派生;
base*base_ptr=nullptr;
无效集ptr(基本*ptr)
{
如果(!动态投影(ptr))
抛出std::logic_错误(“检查您的用户代码”);
基本ptr=ptr;
}
允许的\u派生\u t*ptr()常量
{return static_cast(base_ptr);}
};
如果我在调用
set\u ptr
之前调用它,它是
ptr()
方法安全的吗?因为在设置指针之前,
base\u ptr
不是必需的类型(
allowed\u derived\t
),但是,动态指向对象不是错误的类型(因为没有指向对象)


在这种情况下,标准说明了什么?

所有格式良好的指针对指针强制转换都保证源类型的空指针安全地转换为目标类型的空指针

对于
dynamic\u cast
,它在

5.2.7动态播放

4如果在指针情况下v的值是空指针值,则结果是T类型的空指针值

对于
static\u cast
,它在

5.2.9静态播放

11[…]空指针值(4.10)转换为目标类型的空指针值


所有其他类型转换都提供了类似的保证。

所有格式良好的指针到指针转换都保证源类型的空指针安全地转换为目标类型的空指针

对于
dynamic\u cast
,它在

5.2.7动态播放

4如果在指针情况下v的值是空指针值,则结果是T类型的空指针值

对于
static\u cast
,它在

5.2.9静态播放

11[…]空指针值(4.10)转换为目标类型的空指针值


所有其他强制转换都提供类似的保证。

静态强制转换检查转换在编译时是否有效,因此强制转换指针的运行时值不起任何作用

所以它是安全的,
nullptr
将在运行时导致
nullptr


对于任何其他类型的强制转换都是如此。

static\u cast
检查转换在编译时是否有效,因此强制转换指针的运行时值不起任何作用

所以它是安全的,
nullptr
将在运行时导致
nullptr


对于任何其他类型的演员来说都是如此。

虽然结论是正确的,但你没有抓住要点。在多重继承的强制转换中,
static\u cast
可以是算术运算。因此(比如)0x10000的指针值可能会变成0xFFFC。实际上,运行时检查对于在此类强制转换中使
nullptr
仍然是
nullptr
是必要的。编译器可能需要插入这样的检查。虽然结论是正确的,但您没有抓住要点。在多重继承的强制转换中,
static\u cast
可以是算术运算。因此(比如)0x10000的指针值可能会变成0xFFFC。实际上,运行时检查对于在此类强制转换中使
nullptr
仍然是
nullptr
是必要的。编译器可能需要插入这样的检查。