【问题标题】:C++ difference between adding const-ness with static_cast and const_cast of "this" object?C++ 与 static_cast 和“this”对象的 const_cast 添加 const-ness 的区别?
【发布时间】:2012-06-23 01:30:25
【问题描述】:

按照 Scott Meyers 的说法,为了防止在 getter 的 const 版本和 getter 的非常量版本中重复代码,请从非常量版本调用方法的 const 版本:static_cast<const A&>(*this).Methodology(); 然而,由于过度使用 Visual Assist X Intellisense 导致意外使用,我输入了:const_cast<const A&>(*this).Methodology();,它工作得很好。

在这种情况下,使用特定演员表有什么不同?

使用的 IDE:Visual Studio 2010。

【问题讨论】:

  • 我想知道为什么 Scott 提倡使用 static_cast 而 const_cast 似乎在这里更合适,也更清楚地表达了意图?还是您没有完全按照他的意思使用它?
  • @stijn:我也想知道同样的事情。 const_cast 对我来说感觉稍微自然一些,即使是添加 const 的更安全的方向。
  • @CharlesBailey:看看我的回答,可能会明白他为什么不推广另一个。
  • @stijn:看看我的回答,可能会明白他为什么不推广另一个。
  • @Casey:这不是真的。在您引用的项目中,他专门选择static_cast 而不是const_cast添加 const 到引用类型。我认为这是您所问问题的核心。

标签: c++ static-cast const-cast


【解决方案1】:

假设this的类型为A*,则没有区别。

一般const_cast 可以丢弃const 说明符(来自任何级别的间接或模板参数)

如果目标类型在源的类型层次结构中,static_cast<> 可以将一个类型转换为另一个类型。

他们不能做彼此的工作。

他们在你的情况下都工作的原因是因为你已经引入 const-ness,而不是把它拿走(从函数的非 const 版本调用 @987654326 的类型@ 是 A*,没有常量)。你也可以写

const A& tmp = *this;
tmp.Methodology();

而且它不需要任何铸造就可以工作。强制转换是为了方便和简洁,不必引入新变量。

注意:您可以在此处使用static_cast<>,因为您知道您正在转换为正确的类型。在其他情况下(当您无法确定时),您需要使用 dynamic_cast<> 进行运行时类型检查以确保转换有效

【讨论】:

  • A 是类类型,this 默认为const * A
  • @Casey - 我想那么多;关键是您正在执行此操作的类,而不是子类(在这种情况下,const_cast<> 会失败)
  • @Casey - 如果你在 const 成员函数中,this 的类型是 const A*(更准确地说是 const A* const),否则它是 A*(更准确地说是 @987654340 @)
  • @Attila this 本身是一个标量右值,因此永远不会是 const
  • @FredOverflow - 很高兴知道 :) 我认为它是 const 所以你不能修改它,但右值也有意义
【解决方案2】:

在重新阅读Effective C++ 3rd Ed. 的第 3 条后,我意识到他实际上是在提倡使用 both。添加 const 以调用 const 版本,然后丢弃返回值的 const-ness(如果有的话)。在我的特殊情况下,没有 const 返回值,只有一个 const 函数,因此不需要 const_cast 包装版本,实际上导致 所讨论的两个调用之间没有区别强>

(第 13 页)第 3 项:使用 const 尽可能

...

(第 23 页)避免重复 const const 成员函数

...你真正想做的是实现 operator[] 功能 一次并使用两次。也就是说,您想要一个版本的 operator[] 调用另一个。这让我们抛弃了 constness。

...抛弃返回值上的 const 是安全的,在这种情况下, 因为调用非const 运算符[] 的人一定有一个 首先是非const 对象....所以拥有非const operator[] 调用 const 版本是避免代码的安全方法 重复,即使它需要演员表...

class TextBlock {
public:

...

    const char& operator[](std::size_t position) const      //same as before
    {
        ...
        ...
        ...
        return text[position];
    }

    char& operator[](std::size_t position)        //now just calls const op[]
    {
        //cast away const on op[]'s return type;
        //add const to *this's type;
        //call const version of op[].
        return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
    }
...
};

如您所见,代码有两种类型转换,而不是一种。我们想要 non-const operator[] ...为了避免无限递归,我们必须 指定我们要调用const operator[],但是没有 直接的方法来做到这一点。相反,我们将 *this 从它的原生类型转换 TextBlock&const TextBlock&。是的,我们使用 cast 来添加 常量!所以我们有两种强制转换:一种将 const 添加到 *this (这样我们对 operator[] 的调用将调用 const 版本),第二个到 从 *const operator[] 的返回值中删除 const

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    相关资源
    最近更新 更多