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



根据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"有什么意义吗?

你在这里抛弃了const的本质:

char* ch = (char*) p;

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

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

还要注意的是,在C++中,最好明确你的意图,

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

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

如果const int* const p指向编译时常数,则您的示例将使应用程序崩溃,在丢弃恒定性时,您需要确定自己在做什么。

C++是一种成人语言,永远不会为了短暂的安全而牺牲额外的能力,这是代码作者的选择,是留在安全区,还是使用cast运算符,向C/asm更近一步。

C/C++可以让你做很多让你"伤害"自己的事情。在这里,去掉pconst是"合法的",因为编译器假设您知道自己在做什么。这是否是一种好的编码风格是另一回事。

当你做这样的事情时,你要为它可能产生的任何副作用和问题承担责任。这里,如果参数中指向的内存是静态内存,则程序可能会崩溃。

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

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

C型演员阵容相当于一个标志,上面写着"我知道我在这里做什么"。在大多数情况下,这是错误的。

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

使用c++cast:const_cast<...>(...):的方法相同

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

在这种情况下(我希望)你能立即看到正在发生的事情——你只是摆脱了恐慌。

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

int* q = (int*) p;

原则上,你不应该使用这样的强制转换,因为设计和编写正确的程序不需要它。通常,const_cast用于对程序进行快速和临时的更改(检查某些内容),或者使用一些设计不正确的库中的函数。

最新更新