19

根据 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。

4

2 回答 2

8

假设类型thisA*,则没有区别。

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

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

他们不能做彼此的工作。

它们在您的情况下都起作用的原因是因为您引入了const-ness,而不是把它拿走了(从函数的非 const 版本调用thisis的类型A*,没有 const)。你也可以写

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

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

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

于 2012-06-20T20:30:09.047 回答
6

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

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

...

(p. 23)避免 const const 成员函数中的重复

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

...在这种情况下,丢弃返回值上的const是安全的,因为调用非const operator[]的人首先必须有一个非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]);
    }
...
};

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

于 2012-06-20T21:49:41.167 回答