简体   繁体   English

添加const-ness与static_cast和const_cast的“this”对象之间的C ++区别?

[英]C++ difference between adding const-ness with static_cast and const_cast of “this” object?

As per Scott Meyers, to prevent repetition of code in the const version of a getter and the non-const version of a getter, call the const version of the method from the non-const version: static_cast<const A&>(*this).Methodology(); 根据Scott Meyers的说法,为了防止在const版本的getter和非const版本的getter中重复代码,请从非const版本调用该方法的const版本: static_cast<const A&>(*this).Methodology(); however , in accidental usage due to an overzealous Visual Assist X Intellisense I typed: const_cast<const A&>(*this).Methodology(); 然而 ,由于过度热心的Visual Assist X Intellisense I意外使用我键入: const_cast<const A&>(*this).Methodology(); and it worked just fine. 它运作得很好。

What are any and all differences in this case with using a particular cast? 在这种情况下使用特定演员阵容有什么区别?

IDE in use: Visual Studio 2010. 正在使用的IDE:Visual Studio 2010。

Assuming that the type of this is A* , there is no difference. 假设类型thisA* ,没有任何区别。

In general const_cast can cast aways the const specifier (from any level of indirection or template parameter) 一般来说, const_cast可以抛弃const说明符(从任何级别的间接或模板参数)

static_cast<> can cast a type to another if the target type is in the source's type hierarchy. 如果目标类型在源的类型层次结构中, static_cast<>可以将类型转换为另一个类型。

They cannot do each other's work. 他们不能做彼此的工作。

The reason they both worked in your case is because you have introduced const-ness, as opposed to having taken it away (calling from the non-const version of the function the type of this is A* , no const). 他们都在你的情况下,工作的原因是因为你已经引入了常量性,而不是已经采取它拿走(从非const版本的函数调用的类型, thisA* ,没有常)。 You could just as well have written 你也可以写

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

and it would have worked without the need for any casting. 并且它可以在不需要任何铸造的情况下工作。 The casting is used for convenience and terseness to not have to introduce a new variable. 为了方便和简洁而使用铸件而不必引入新的变量。

Note : you can use static_cast<> here as you know that you are casting to the right type. 注意 :您可以在此处使用static_cast<> ,因为您知道正在转换为正确的类型。 In other cases (when you cannot be sure) you need to use dynamic_cast<> that does a runtime type check to ensure the conversion is valid 在其他情况下(当您无法确定时),您需要使用运行时类型检查的dynamic_cast<>来确保转换有效

After re-reading Item 3 from Effective C++ 3rd Ed. 重新阅读Effective C++ 3rd Ed. I realize that he was actually advocating using both . 我意识到他实际上主张同时使用两者 Add const to call the const version, then cast away the const-ness of the return value (if there is one). 添加const来调用const版本,然后抛弃返回值的常量(如果有的话)。 In my particular case, there is no const return value, just a const-function so the wrapped-by-const_cast<> version is not needed and in effect causes there to be no difference between the two calls in question 在我的特定情况下,没有const返回值,只有一个const函数,因此不需要包装const_cast <>版本,实际上导致两个调用之间没有区别

(p. 13) Item 3: Use const whenever possible (第13页) 第3项: 尽可能 使用 const

... ...

(p. 23) Avoiding Duplication in const and Non- const Member Functions (第23页) 避免 const const 成员函数的 重复

...What you really want to do is implement operator[] functionality once and use it twice. ...你真正想做的是实现operator []功能一次并使用它两次。 That is, you want to have one version of operator[] call the other one. 也就是说,你想让一个版本的operator []调用另一个版本。 And that brings us to casting away constness. 这使我们抛弃了常数。

...Casting away the const on the return value is safe, in this case, because whoever called the non- const operator[] must have had a non- const object in the first place....So having the non- const operator[] call the const version is a safe way to avoid code duplication, even though it requires a cast... ...在返回值上抛弃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]); } ... }; 

As you can see, the code has two casts, not one. 如您所见,代码有两个演员,而不是一个。 We want the non- const operator[] ... To avoid infinite recursion, we have to specify that we want to call the const operator[] , but there's no direct way to do that. 我们想要非const运算符[] ...为了避免无限递归,我们必须指定我们想要调用const运算符[] ,但没有直接的方法来做到这一点。 Instead, we cast * this from its native type of TextBlock& to const TextBlock& . 相反,我们将* this从其原生类型的TextBlock转换const TextBlock& Yes, we use cast to add const ! 是的,我们使用强制转换来添加const So we have two casts: one to add const to * this (so that our call to operator[] will call the const version), the second to remove the const from the *const operator[]'s return value. 所以我们有两个强制转换:一个将const添加到* this (这样我们对operator []的调用将调用const版本),第二个从* const operator []的返回值中删除const

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM