根据我读过的一些教程,“const”声明使变量“不变”,即后来无法改变。
但是我发现这个const声明会引起不便,因为编译器有时会出现像
这样的错误
"cannot convert const int to int"
或类似的东西。
我发现自己还是会因为删除它而作弊。
问题: 假设我小心不改变源代码中的变量,我可以高兴地忘记这个const的东西吗?
提前致谢
答案 0 :(得分:51)
const
来避免错误,并且您可以从它添加的大量帮助中受益,以确保您的代码正确无误。
当然,您可以告别语言提供的所有帮助,并告诉编译器不要再告诉您代码中的错误。相反,您将不得不稍后询问调试器您的错误所在。不确定这是否更好。
答案 1 :(得分:14)
在C ++中,“const”可以应用于变量(使其不可更改)或函数(使其无法更改其他内容)。
我对“const”的使用不仅仅是为了防止我的代码更改我的变量。这是为了防止一些白痴的代码改变我的变量(特别是如果白痴是我从现在起六个月后),并防止我的代码改变一个白痴暴露的关键变量(特别是如果这个白痴是我六个月前)。
答案 2 :(得分:6)
如果你小心,是的。但这是人类错误。此外,您不会让编译器有机会围绕这些常量进行优化。
您收到的错误消息是因为您尝试更改const int
。只需将值赋给(非常量)int
,就可以根据需要进行更改。
Const帮助你,尝试将更多的东西洒在周围并听取编译器。这将有助于您生成更好的代码。
答案 3 :(得分:3)
即使您和您工作的每个人都从未犯过错误,在方法声明中使用const也有助于记录您的界面。
答案 4 :(得分:3)
如果没有const,你会失去一些有用的语言功能考虑:
void f(const MyClass& m);
void f(const int& i);
// ...
f(MyClass()); // OK, can pass temporary as const reference
f(5); // OK as well, 5 is a temporary int
如果你认为'const'是可选的并且摆脱它:
void f(MyClass& m);
void f(int& i);
// ...
f(MyClass()); // Error, cannot pass temporary as non-const reference
f(5); // Error, same as above
答案 5 :(得分:2)
使用'const'背后的想法是,在尝试改变变量的值时,确保编译器错误(当使用const
时),你不想这样做。它基本上是在错误检查中构建的,并且由于许多原因而有用。
这在外部接口和公共方法等情况下尤其有用,可以保证调用者不会修改传递的值。
const
还锁定了不修改的意图,并防止意外分配。
虽然使const
强制使用是必要的,但这是非常有用和良好的做法。
以下是您可能希望查看的有用说明:http://duramecho.com/ComputerInformation/WhyHowCppConst.html
答案 6 :(得分:1)
你可以忘记它但是如果编译器强迫它在你身上不是很好吗?这样,你的“const”变量实际上保持不变。
答案 7 :(得分:1)
它总是可选的。如果它的所有代码确定你可以忘记它(我不推荐它,因为它可以保护你),但是当你与他人互动时,你实际上是在为他们提供一个合同,你不会改变他们的对象或调用函数不会更改对象的状态。当您不熟悉其他代码或者您没有源代码时,这可能是非常宝贵的。
答案 8 :(得分:1)
首先回答你的问题:
是的,你可以。但是,只有当你小心的时候,从现在到永恒使用你的代码的每个人都要小心。
所以,总的来说,你最好不要考虑为什么 应该制作const
的内容以及何时不应该这样做。
另一种探索const为什么会产生影响的技巧是首先尝试使一切 const,直到你有正当理由改变某些东西,然后,只有这样才能删除最小数量的consts直到它又有效了。
很高兴看到你正在考虑这个问题 - 它比大多数人都要多。
答案 9 :(得分:0)
人们在开始使用const关键字时通常会遇到此问题。相信我,这真的很有帮助。把它留给编译器来处理变量的代价,而不是你不小心改变它的值。
答案 10 :(得分:-4)
更改不应更改的内容是最常见的错误来源之一。 因此,值得指定const,因为它可以防止您做错事。你为什么要放弃呢?
const double PI = 3.14159265358979;
PI=4; // generates a compiler error (good)
c ++表示法存在一些问题,因为常量只能初始化,而不是第一次分配,有时候,初始化时没有值。
class A {
private:
const int num;
public:
A(int x, int y) : num(0) { // oops, I don't yet know what num should be
while ( ... ) {
}
num = ...;
}
};
这个方法的出路是定义一个计算num值的私有函数 但有时这意味着在构造函数中不是一个干净的代码块,而是强迫您以笨拙的方式将其拆分为多个部分,这样就可以初始化变量。
class A {
private:
const int num;
int computeNum(int x, int y) { ... }
public:
A(int x, int y) : num(f(x,y)) {
}
};
有时候,你有一个通常应该是const的值,但是你想要在语义上有意义时有选择地覆盖它。例如,社会安全号码不会改变,除非您的身份被盗。所以你只有一个名为createNewSSN()的方法,它改变了原本不变的ssn
class Person {
private:
const int ssn;
public:
Person(int ssn_) : ssn(ssn_) {}
void createNewSSN(int newssn) {
log << "Changed SSN: " << ssn << " to " << newssn << "\n";
*(int*)&ssn = newssn; // trust me, this is a special case....
}
};