【问题标题】:use `static_cast` for downcasting over a null pointer (single or multiple inheritance)使用 `static_cast` 向下转换空指针(单继承或多继承)
【发布时间】:2016-12-12 19:40:19
【问题描述】:

正如标题所说,如果我将一个指向基类的指针转换为派生类,当指针为空时,从 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); }
};

如果我在调用set_ptr 之前调用它,ptr() 方法是否安全?因为,在设置指针之前,base_ptr 不是所需的类型(allowed_derived_t),但是,动态指向的对象不是错误的类型(因为没有指向的对象)。

标准在这种情况下怎么说?

【问题讨论】:

    标签: c++ pointers polymorphism downcast


    【解决方案1】:

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

    对于dynamic_cast,在

    中说明

    5.2.7 动态投射

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

    对于static_cast,在

    中说明

    5.2.9 静态转换

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

    所有其他演员都提供类似的保证。

    【讨论】:

      【解决方案2】:

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

      所以这是安全的,nullptr 将在运行时生成 nullptr

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

      【讨论】:

      • 虽然结论是正确的,但您没有切中要害。在多重继承的转换中,static_cast 可以是算术运算。所以(比如说)0x10000 的指针值可能会变成 0xFFFC。实际上,需要进行运行时检查才能使nullptr 在此类转换中仍然是nullptr。编译器可能需要插入此类检查。
      猜你喜欢
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 2013-06-13
      • 2016-09-02
      • 2016-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多