使用const_cast来添加恒常性 - 坏主意?
Using const_cast to add const-ness - bad idea?
众所周知,应避免使用const_cast来消除指针的恒常性。
但是反过来呢?
对于我的用例,我有一个从非常量源缓冲区复制数据(字节)的函数。 我认为一个好的设计决策是根据该源缓冲区完全常量声明参数。
void copyfunction(const char* const data) { ... }
对于如下所示的函数调用,这将导致指针类型错误"const char* const <-> char*"。
void main() {
char sourcebuffer[] = {0x00};
copyfunction(sourcebuffer);
}
当然,现在我可以简单地将sourcebuffer
声明为 const,但就我而言,我无法访问该变量,因为它来自不同的代码位置(外部库)。
void main() {
char sourcebuffer[] = {0x00};
copyfunction(const_cast<const char* const>(sourcebuffer));
}
但是,超出的代码会起作用,但它是好的风格(根据我的用例)?
我认为将copyfunction
的参数声明为 const 可以确保用户不会修改(只读)指针或源缓冲区本身的位置。 因此,在这种情况下,const_cast只是使函数调用成为可能的必要邪恶,而不是故意删除指针的恒定性......
迎接
你不应该使用const_cast
来添加const
,因为:
-
这是不必要的。
T*
隐式转换为const T*
。您的问题指出char sourcebuffer[] = {0x00}; copyfunction(sourcebuffer);
是一个错误,但事实并非如此。 -
它可能(尽管不太可能)有害。它可以从指针类型中删除
volatile
,这不是此处的意图,如果sourcebuffer
声明为volatile sourcebuffer[]
,将导致未定义的行为。
您不应该使用const_cast
来添加const
因为
-
在操作安全的情况下,几乎总是不需要。
int*
隐含地变成了const int*
。 -
它可以做一些你不想让它做的事情。 它可以剥离
volatile
,或者让你错过const
被添加到变量中的其他地方,而你的const_cast
现在默默地剥离它们的事实。 -
在需要添加
const
的情况下,它的使用是危险的,很难推理。
在某些情况下,您需要调用const_cast
才能添加不会隐式发生的const
。
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
,但它不会隐式发生。
它的副作用是修改*bar
是未定义的行为,因为它修改了声明为const
的变量(它使bar
,一个int*
,指向foo
const int
)。
因此,虽然需要const_cast
才能编译assign_ptr
调用,但这是因为它不安全。const_cast
并没有使它更安全,它只是隐藏了错误。
这是矩形正方形问题的特定情况。 正方形不是矩形,因为如果您更改正方形的宽度,其高度也会更改,而修改矩形时不会发生这种情况。 同样,int**
也不int const**
. (请注意,不可变的正方形是一种不可变的矩形;正是突变导致了这个问题。 在指针的情况下,int*const*
是一个int const*const*
:"更高级别"指针的可变性导致了问题。
- const_cast静态数组以添加恒常性
- 自动模板参数、数据成员和恒常性
- 有没有办法检测自身内部的类恒常性?
- 为什么const_cast删除指针的恒常性,而不删除指向常量的指针的恒常性?
- 对指针和恒常性兼容性的引用
- 自定义容器中的括号运算符中的恒常性
- C++ 重载分辨率和恒常性
- C++17类模板演绎常性
- C++ 函数匹配和恒常性
- 如何忽略函数模板中的恒常性?
- 常量自动和对象恒常性
- 比较运算符 == 中的共享指针恒常性
- 添加额外的恒常性会导致编译器错误
- 删除模板化函数中的恒常性
- 无法正确理解我的恒常性
- 模板转换运算符优先级和恒常性
- const_iterator和恒常性const_iterator::value_type
- 使用const_cast来添加恒常性 - 坏主意?
- C++ 逻辑恒常性和 const方法的按值返回
- C++。为什么我不能编译此代码?使用const_cast去除恒常性有什么问题?