关于c ++中的关键字“const”

时间:2013-11-28 16:38:24

标签: c++

根据c ++语法,const int* const p意味着p指向它并且它的值不能被重写。但是今天我发现如果我这样编码:

void f(const int* const p)  
 { 
     char* ch = (char*) p;
     int* q = (int*) ch;
     (*q) = 3;  //I can modify the integer that p points to
 }

在这种情况下,关键字“const”将失去它的效果。使用“const”有什么意义吗?

5 个答案:

答案 0 :(得分:6)

你在这里抛弃了const

char* ch = (char*) p;

实际上,你说的是“我知道我在做什么,忘记你是const,我接受后果。” C ++允许你做这样的事情,因为有时它可能是有用/必要的。但它充满了危险。

请注意,如果传递给函数的参数确实是const,那么您的代码将导致未定义的行为(UB)。你无法从函数内部知道。

另请注意,在C ++中,最好使您的意图清晰,

int* pi = const_cast<int*>(p);

这清楚表明你的目的是抛弃const。它也更容易搜索。关于危险和UB的相同警告适用。

答案 1 :(得分:1)

如果const int* const p指向编译时常量,那么您的示例会使应用程序崩溃,当您抛弃常量时,您需要确定自己在做什么。

C ++是成人的一种语言,永远不会因为短暂的安全而牺牲额外的力量,代码作者的选择是选择是留在安全区还是使用演员操作员并向C / asm靠近一步。

答案 2 :(得分:0)

C / C ++会让你做很多事情,让你自己“伤害”自己。在这里,抛弃const p是“合法的”,因为编译器会假设您知道自己在做什么。这是否是良好的编码风格是另一回事。

当您执行此类操作时,您将承担任何副作用及其可能产生的问题的责任。这里,如果参数中指向的内存是静态内存,程序可能会崩溃。

简而言之,仅仅因为你可以做某事并不意味着这是一个好主意。

答案 3 :(得分:0)

const关键字是一种使用编译器来捕获编程错误的方法,仅此而已。它没有声明在运行时内存的可变性,只是如果你直接修改值,编译器应该对你大喊大叫(不使用C风格的强制转换)。

C风格的演员阵容几乎就是“我知道我在这里做什么”的标记。在大多数情况下,这是错误的。

答案 4 :(得分:0)

在此处更改指针的类型。使用这样的强制转换(C型)转换,您可以将其更改为任何可能的指针,没有问题。

与使用c ++强制转换的方式相同:const_cast<...>(...)

int* p_non_const = const_cast<int*>(p);

在这种情况下(我希望)你会立即看到发生了什么 - 你只是摆脱了常量。

请注意,在您的程序中,您也不需要temprorary变量ch。你可以直接这样做:

int* q = (int*) p;

原则上你不应该使用这样的演员,因为正确设计和编写的程序不需要它。通常,const_cast用于程序中的快速和临时更改(以检查某些内容)或使用来自某些未正确设计的库中的函数。