使用const_cast添加const-ness-好主意吗? [英] Using const_cast to add const-ness - bad idea?
问题描述
我们都知道应该避免使用const_cast删除指针的常数性.
as we all know the usage of const_cast to remove the const-ness of a pointer should be avoided.
但是反过来又如何呢?
对于我的用例,我有一个从非常量源缓冲区复制数据(字节)的函数. 我认为一个好的设计决策是根据该源缓冲区完全为const声明参数.
For my use case I have a function that copies data (bytes) from a non-const source buffer. I thought a good design decision would be to declare the parameter according to that source buffer fully const.
void copyfunction(const char* const data) { ... }
对于如下所示的函数调用,将导致指针类型错误'const char * const<-> char *'.
For a function call like below this would lead to a pointer-type error 'const char* const <-> char*'.
void main() {
char sourcebuffer[] = {0x00};
copyfunction(sourcebuffer);
}
当然,现在我可以简单地将sourcebuffer
声明为const,但是在我的情况下,由于它来自不同的代码位置(外部库),因此我无法访问该变量.
Sure, now I could simply declare the sourcebuffer
as const but in my case I don't have access to that variable because it's from a different code location (external library).
void main() {
char sourcebuffer[] = {0x00};
copyfunction(const_cast<const char* const>(sourcebuffer));
}
但是超出范围的代码仍然可以工作,但是它是好的样式吗(根据我的用例)?
However the code beyond would work but is it good style (according to my use case)?
我认为将copyfunction
的参数声明为const可以确保用户不修改(只读)指针或源缓冲区本身的位置.
因此,在这种情况下,const_cast仅是启用函数调用的必要条件,而不会故意删除指针的const-ness ...
I thought declaring the parameter of the copyfunction
as const assures the user of not modifying (read-only) the pointer or the location of the source buffer itself.
So in this case the const_cast would only be a necessary evil to enable to function call and not willfully remove the const-ness of a pointer...
礼物
推荐答案
您不应使用const_cast
添加const
,因为
-
在安全操作的情况下,几乎始终不需要这样做.
int*
隐式变成const int*
.
它可以做您不希望做的事情.它会剥离volatile
,或者使您错过以下事实:在变量中的其他位置添加了const
,而您的const_cast
现在却无声地剥离了它们.
It can do something you don't want it to do. It can strip volatile
, or make you miss the fact that const
was added somewhere else in your variables and your const_cast
now silently strips them.
在需要添加const
的情况下,使用它的方式很危险,难以推理.
In the cases where it is required to add const
, its use is dangerous in hard to reason about ways.
在某些情况下,您需要调用const_cast
来添加const
,而这不会隐式发生.
There are cases where you need to call const_cast
in order to add const
that will not happen implicitly.
void assign_ptr( int const*& lhs, int const* rhs ) { lhs = rhs; }
int const foo = 7;
int* bar = nullptr;
assign_ptr( const_cast<int const*&>(bar), &foo );
*bar = 2; // undefined behavior!
std::cout << foo << "@" << &foo << "\n"; // will print probably 7@something
std::cout << *bar << "@" << bar << "\n"; // will print probably 2@same address as above!
上面对assign_ptr
的调用仅添加了const
,但不会隐式发生.
the above call to assign_ptr
only adds const
, but it will not happen implicitly.
它的一个副作用是对*bar
的修改是未定义的行为,因为它修改了声明为const
的变量(它使bar
,int*
指向foo
和const int
)
A side effect of it is that modification of *bar
is undefined behavior, as it modifies a variable declared const
(it makes bar
, a int*
, point at foo
a const int
).
因此,虽然需要const_cast
进行assign_ptr
调用编译,但这是因为它不安全. const_cast
并不能使其更安全,它只是隐藏了错误.
So while const_cast
is required to make the assign_ptr
call compile, it is because it was unsafe. The const_cast
doesn't make it safer, it just hides the error.
这是矩形正方形问题的一种特殊情况.正方形不是矩形,因为如果更改正方形的宽度,其高度也会改变,并且在修改矩形时不会发生这种情况.同样,int**
不是int const**
. (请注意,不可变的Square是不可变的Rectangle;它是导致问题的突变.在指针的情况下,int*const*
是int const*const*
:更高级别"的指针的可变性会引起问题. )
This is a specific case of the rectangle-square problem. Squares are not Rectangles, because if you change the width of a Square its height also changes, and this does not happen when you modify a Rectangle. Similarly, int**
are not int const**
. (Note that immutable Squares are a kind of immutable Rectangle; it is the mutation that causes the issue. In the case of pointers, a int*const*
is a int const*const*
: the mutability of the "higher level" pointers causes the problem.)
这篇关于使用const_cast添加const-ness-好主意吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!