我的 const
属性出了问题。由于功能原因,我无法完全保护我的const数据。函数可以修改所有内容。
const reference
是一件非常糟糕的事情,因为它需要一个地址;如果它是const变量的地址,则很可能仍然可以更改或修改变量数据。我的数据是可写的。解析器无法阻止(忽略)这种代码,因为它在C ++中完全合法。
scanf("%d", &const_var);
如何锁定我的数据并使我的const数据不可修改(或不可写)?
答案 0 :(得分:3)
在这种情况下......
scanf("%d", &foo); // Out of range!!!
确实可以修改 ... foo
,或者几乎任何其他事情都可以发生。编译器无法捕获此信息,因为scanf
使用旧式c varargs
,它允许传递任意类型的任意数量的参数,而不进行任何检查。没有尝试确保传递的参数是一个地址,更不用说int的地址,当然也不是非const int的地址。
对于更安全的C ++代码,请完全避免使用printf/sscanf
系列函数。
Lint或其他一些源代码检查器可以在这里提供帮助。我没有尝试过这个具体案例。
答案 1 :(得分:1)
你不能直接保护自己免受这种情况的伤害。如果将常量放入可写存储器中,则可以始终获取该常量的地址并以一种或另一种方式对其进行修改。但请记住,该标准说,修改常量值被认为具有未定义的行为。
如果您希望常量不可修改,可以进行解决方法并使用宏:
#define foo 100
这是一个技巧,因为它会将源中所有出现的foo
交换为100
,但是没有人能够在运行时修改它的值(根据定义,100是100)
但是,我会避免使用宏。您可以改用另一种解决方法:定义一个函数:
constexpr int FooValue()
{
return 100;
}
没有人能够修改它,但是这个解决方案允许你在类或命名空间中嵌入这样的“常量”。如果你使用可以处理C ++ 11的编译器,使用constexpr将允许你在任何地方输入这个函数,你可能已经插入了一个常量,例如:
int array[FooValue()];
答案 2 :(得分:1)
C ++不是一种安全的语言。在C ++中,你只能保护自己免受意外事故,而不是perfidy。如果用户想要改变他们不应该改变的东西,那就像这样简单:
void SomeFunc(const Obj &dontChange)
{
Obj &change = const_cast<Obj &>(dontChange);
change.X = ...;
}
您无法做任何事情来保护自己免受确定违反您的代码与他们之间的合同的用户的侵害。您只能保护自己免受意外试图违反合同的用户的侵害。你甚至无法保护你班级的私人成员,因为他们可以简单地将类型转换为其他内容并直接戳入内存。
你最好的选择是:不要担心。如果用户使用某个变量做错了,那么结果发生的任何破坏就是他们的错误。