所以我在一个看起来像这样的函数中解析C字符串:
void parse(const char** params, int numParams);
我想从存储在params中的一个字符串中提取一些信息,所以我编写的代码如下:
char* charPointer;
charPointer = params[0];
编译器并不喜欢这样,并告诉我它无法从const char *转换为char *。我理解这背后的原因(理论上我可以写信给charPointer指出的地址,但不能写params [0],如果它让我),但我不明白我应该如何绕过它。我知道有两种方法可以解决这个错误,但我不知道哪一个是#34;正确的"或者他们之间真正的区别。第一个是:
const char* charPointer;
charPointer = params[0];
第二种方法是:
char* charPointer;
charPointer = const_cast<char*>(params[0]);
哪个更好,为什么?
答案 0 :(得分:4)
哪个更好,为什么?
const char* charPointer;
charPointer = params[0];
肯定比使用
强制删除限制更好char* charPointer;
charPointer = const_cast<char*>(params[0]);
解析字符数组通常不需要更改它,因此最好留下它const
。
答案 1 :(得分:4)
const_cast
是安全的,如果指针确实指向非const的东西,那么修改它不是问题。如果该值最初是const
,那么使用const_cast
去掉const然后写入它基本上是未定义的行为(例如,代码的其他部分可能假设值不会改变,所以你的修改有时只会生效。
所以一定要使用这个版本:
const char* charPointerr = params[0];
一般来说,如果你需要诉诸const_cast
,你可能正在做一些事情......如果没有错,那么至少是丑陋的。如果你不确定它是否只是丑陋或完全错误,那么它可能是错误的。
由于未定义的行为导致事情可能出现严重错误的示例:
const bool do_it = true;
bool *ptr = const_cast<bool*>(&do_it);
*ptr = false;
// optimizer probably thinks this is always true
if (do_it) initiate_nuclear_first_strike();
在使用调试版本进行开发时,一切似乎都有效。然后,部署发布版本(当然,没有测试,因为匆忙),以及 BOOM ,世界末日。 UB就像那样危险(旁注:UB的效果也可能完全模糊,不像这个例子那么容易理解)。
答案 2 :(得分:1)
铸造几乎总是代码味道。我曾经为const_cast
找到的唯一合法用途是将const数据传递给你知道不会修改数据的遗留库函数,但是在古代没有const说明符的情况下编写。
无论如何,你为什么要把它扔掉?在这种情况下,您不需要。 Const正确性是编写正确代码的一大福音。我发现制作一些不需要改变的常量是一件好事。
答案 3 :(得分:1)
const_cast 只有在您投射最初为非const的变量时才是安全的。例如,如果你有一个带有const char *参数的函数,并传入一个可修改的char * ,那么const_cast这个参数可以安全地返回char *并且修改它。但是,如果原始变量实际上是const,那么使用const_cast将导致未定义的行为
<textarea id="myWordsToCount"></textarea>
<span id="wordcount"></span>
是更好的方法,也可以更好地初始化和声明在同一行。
答案 4 :(得分:1)
将指向const的指针转换为指向非const的指针允许您通过指针写入常量对象。
写入常量对象是未定义的行为。
C ++语言规范非常明确地指出当您调用未定义的行为时会发生什么 - 程序的整个逻辑变得未定义,编译器处于没有义务合理行事,即使在程序的不相关部分,也很难理解程序的行为 -
知道这一点,再问自己一个问题。 : - )