首页 文章

const_cast vs reinterpret_cast

提问于
浏览
7

参考SO C FAQ When should static_cast, dynamic_cast and reinterpret_cast be used? .

const_cast用于删除或添加const到变量,它是唯一可靠,定义和合法的方法来删除constness . reinterpret_cast用于更改类型的解释 .

我理解为什么一个const变量应该只使用const_cast转换为非const,但我无法找出使用reinterpret_cast而不是const_cast来添加constness的问题的合理理由 .

我知道使用reinterpret_cast甚至添加constness是不是很理智,但是使用reinterpret_cast来增加常量会是UB还是潜在的定时炸弹?

我在这里感到困惑的原因是因为声明

很大程度上,reinterpret_cast的唯一保证是,如果将结果转换回原始类型,您将获得完全相同的值 .

因此,如果我使用reinterpret_cast添加constness,并且如果你将结果重新解释为原始类型,它应该返回原始类型而不应该是UB,但这违反了一个事实,即只应该使用const_cast来删除constness

在单独的注释中,该标准保证您可以使用重新解释案例添加Constness

5.2.10重新解释强制转换(7)......当“指向T1的指针”类型的prvalue v转换为“指向cv T2的指针”类型时,结果为static_cast(static_cast(v)) T1和T2是标准布局类型(3.9),T2的对齐要求不比T1更严格........

5 回答

  • 1

    reinterpret_cast 更改对象内数据的解释 . const_cast 添加或删除 const 限定符 . 数据表示和常量是正交的 . 所以有不同的演员关键词是有意义的 .

    因此,如果我使用reinterpret_cast添加constness,并且如果将结果重新解释为返回原始类型,则应该返回原始类型并且不应该是UB,但这违反了一个事实,即只应使用const_cast来删除constness

    那甚至不会编译:

    int * n = new int;
    const * const_added = reinterpret_cast<const int *>(n);
    int * original_type = reinterpret_cast<int*>(const_added);
        // error: reinterpret_cast from type ‘const int*’ to type ‘int*’ casts away qualifiers
    
  • 0

    你不应该只是添加 constreinterpret_cast . reinterpret_cast 应该主要是:重新解释指针(或其他) .

    换句话说,如果你从 const char*char* (希望因为有更改),那么 const_cast 就是你的朋友 . 那是's really all it'的意图 .

    但是如果你需要从 MyPODType*const char* ,你需要 reinterpret_cast ,而且不需要 const_cast 就可以了 .

  • 4

    有一点要记住:你不能使用 const_cast 来使 const 变量可写 . 如果该const引用引用非const对象,则只能使用它从const引用中检索非const引用 . 听起来很复杂?例:

    // valid:
    int x;
    int const& x1 = x;
    const_cast<int&>(x1) = 0;
    // invalid:
    int const y = 42;
    int const& y1 = y;
    const_cast<int&>(y1) = 0;
    

    实际上,这两者都会编译,有时甚至“工作” . 但是,第二个导致未定义的行为,并且在常量对象放置在只读存储器中时,在许多情况下会终止程序 .

    也就是说,还有一些东西: reinterpret_cast 是最强大的演员,也是最危险的演员,所以除非必须,否则不要使用它 . 当您需要从 void* 转到 sometype* 时,请使用 static_cast . 当朝相反方向运行时,使用内置隐式转换或使用显式 static_cast . 与添加或删除 const 类似,也是隐式添加的 . 关于 reinterpret_cast ,另见C++ When should we prefer to use a two chained static_cast over reinterpret_cast的讨论,其中讨论了一种不那么强硬的替代方案 .

    乌利

  • 0

    我可以想到将reinterpret_cast与const-ness相关联的唯一地方是将const对象传递给接受void指针的API时 -

    UINT ThreadFunction(void* param)
    {
        const MyClass* ptr = reinterpret_cast<const MyClass*>(param);
    }
    
  • 10

    是的,如你所知,const_cast意味着它从特定类型中删除了constness .

    但是,当我们需要为一个类型添加constness时 . 我们有这个理由吗?

    例如,

    void PrintAnything(void* pData)
    {
        const CObject* pObject = reinterpret_cast<CObject*>(pData);
        // below is bla-bla-bla.
    }
    

    reinterpret_cast与'const'无关 .

    const_cast意味着两件事 . 第一个是从类型中删除constness,另一个是为其代码显示 . 因为您可以使用C样式转换来使用它,但这不是明确的,因此不建议这样做 .

    它们的功能不同 . 这绝对是不同的 .

相关问题