我应该使用const_cast吗?

时间:2016-03-18 19:39:26

标签: c++

所以我在一个看起来像这样的函数中解析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]);

哪个更好,为什么?

5 个答案:

答案 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 ++语言规范非常明确地指出当您调用未定义的行为时会发生什么 - 程序的整个逻辑变得未定义,编译器处于没有义务合理行事,即使在程序的不相关部分,也很难理解程序的行为 -

知道这一点,再问自己一个问题。 : - )