使用const_cast添加const-ness-好主意吗? [英] Using const_cast to add const-ness - bad idea?

查看:102
本文介绍了使用const_cast添加const-ness-好主意吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道应该避免使用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,因为

  1. 在安全操作的情况下,几乎始终不需要这样做. 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的变量(它使barint*指向fooconst 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆