是const(c ++)可选吗?

时间:2010-03-19 13:06:16

标签: c++ const

根据我读过的一些教程,“const”声明使变量“不变”,即后来无法改变。
 但是我发现这个const声明会引起不便,因为编译器有时会出现像
这样的错误 "cannot convert const int to int"
或类似的东西。

我发现自己还是会因为删除它而作弊。

问题: 假设我小心不改变源代码中的变量,我可以高兴地忘记这个const的东西吗?

提前致谢

11 个答案:

答案 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....
  }
};