const_cast<> 的正确用法
作为一个常见规则,在 C++ 代码中使用 const_cast<>() 通常被认为是一种不好的做法,因为它(大多数时候)暴露了设计中的缺陷。
虽然我完全同意这一点,但我想知道在什么情况下使用 const_cast<>() 是ok以及唯一的解决方案。
你们能给我一些您知道/遇到过的例子吗?
非常感谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
它几乎被设计为仅与非 const 正确的遗留 API 一起使用,即与您无法更改且具有非 const 接口但实际上不会改变接口上任何内容的函数一起使用
it is pretty much designed to be only used with legacy APIs that are not const correct i.e. with a function you can't change that has non const interface but doesn't actually mutate anything on the interface
正如其他人所说,它的主要目的是从对象中删除 const,以便传递给您知道不会修改参数的非常量正确函数。
有一个技巧(Meyers 提出的?)可以避免代码重复,如下所示:
Like others have said, its primary purpose is to remove
const
from objects in order to pass to non-const correct functions you know won't modify the argument.There is a trick (by Meyers?) to avoid code duplication, and it goes like this:
const_cast
还用于删除volatile
修饰符,如这篇(有争议的)文章中的实践:const_cast
is also used to removevolatile
modifiers, as put into practice in this (controversed) article:http://www.drdobbs.com/184403766
我同意你的说法,即它的正常使用是因为你需要隐藏“设计缺陷”。
IME 的典型使用场景之一是当您尝试将 C++ 与现有 C 代码连接时。许多现有的 C 代码将 C 字符串视为
char *
,即使字符串未修改也是如此,而它们通常表示为在 C++ 中转换为const char *
的内容。这是两种语言之间的阻抗不匹配,通常可以使用 const_cast 来解决。当然,您最好非常确保您所连接的代码不会获得任何有关修改传入数据的可爱想法。我想说,这是一段新的代码味道编写的代码,但对于与旧的 C 和 C++ 代码交互,这是一个必要的邪恶。也就是说,我对任何非 POD 对象都需要
const_cast
的代码非常警惕,因为这通常是一个应该在设计级别而不是代码级别解决的问题。I agree with your statement that its normal use is because you need to hide a 'design flaw'.
IME one of the typical usage scenarios is when you try to interface C++ to existing C code. A lot of existing C code takes C strings as
char *
even when the string is not modified whereas they're usually represented as something that converts to aconst char *
in C++. That's an impedance mismatch between the two languages that you would normally solve by using a const_cast. Of course you'd better be very sure that the code you're interfacing with doesn't get any cute ideas about modifying the data that's being passed in.I would say that it's a code smells in newly written code, but for interfacing with older C and C++ code, it's an necessary evil. That said, I would be extremely wary of code that requires
const_cast
for any non-POD objects as that is normally a problem that should be solved at the design level and not the code level.(在我看来)一种合法的用途是使用
std::set
迭代器。它们始终是 const,以防止更改集合中使用的密钥。更改密钥会破坏集合的内部结构并导致未定义的行为。但是,只要密钥不更改,就可以安全地更改对象中的其他数据。
假设你有一个像这样的 std::set
和一个这样的类:
在上面的例子中,键已经是 const,所以即使你修改了对象,你不能破坏集合的内部结构。
通常,您只能从 set 迭代器中获取
const
引用:但由于键是
const
,因此可以安全地const_cast
取消引用的迭代器:One legitimate use (in my opinion) is with
std::set
iterators. They are alwaysconst
, in order to prevent changing the key used in the set. Changing the key would break the internal structure of the set and cause undefined behavior.However, as long as the key doesn't change it's safe to change other data in the object.
Let's say you have an
std::set
like this:And a class like this:
In the above example, the key is already const, so even if you modify the object, you cannot break the internal structure of the set.
Normally you can only get a
const
reference out of a set iterator:But since the key is
const
, it's safe toconst_cast
the dereferenced iterator:一个非常合法的用法是当您同时拥有 const 和非 const api(分别用于 const 和非 const 对象)时,如
Then 中所示,因为我们不想在我们经常使用的两个函数中重复代码
这当然是假设foo 不会做任何违反 const 语义的事情。
One very legitimate use of this is when you have both a const and non const api (for const and non const objects respectively) as in
Then since we don't want to duplicate the code in both functions we often use
This is of course assuming that foo does not do something that violates the const semantics.
是的,当然,当您无法修改且 const 不正确的调用代码时。应该注意的是,您应该仅将它与对您确定不会修改数据的函数的调用一起使用!
Yes of course, when your calling code that you can't modify and isn't const correct. It should be noted that you should only use it with calls to functions that you know for certain won't modify your data!
C++ Primer(5th Edition)一书中有const_cast用法的例子。
下面的函数返回对 const 字符串的引用
本书随后提到了我们需要非 const 引用的情况。
根据这本书,如果我们知道它是安全的,就应该使用它。
There is an example of const_cast usage in c++ primer(5th edition) book.
Below function returns reference to const string
The book then mentions the case when we want a non const reference.
According to the book, it should be used if we know it is safe to cast.