易错知识点提醒

1.问题的关键是非 const 引用形参 (第 2.5 节) 只能与完全同类型的非 const 对象关联。

2.应该将不修改相应实参的形参定义为 const 引用。如果将这样的形参定义为非 const 引用,则毫无必要地限制了该函数的使用。例如,可编写下面的程序在一个 string 对象中查找一个指定的字符: 
   

 1 // returns index of first occurrence of c in s or s.size() if c isn't 
 2 in s 
 3 // Note: s doesn't change, so it should be a reference to const 
 4 string::size_type find_char(string &s, char c) 
 5 { 
 6 string::size_type i = 0; 
 7 while (i != s.size() && s[i] != c) 
 8 ++i; // not found, look at next character 
 9 return i; 
10 } 


这个函数将其 string 类型的实参当作普通(非 const)的引用,尽管函数并没有修改这个形参的值。 这样的定义带来的问题是不能通过字符串字面值来调用这个函数: 
if (find_char("Hello World", 'o')) // ...

虽然字符串字面值可以转换为 string 对象,但上述调用仍然会导致编译失败。

3.在含有 return 语句的循环后没有提供 return 语句是很危险的,因为大部分的编译器不能检测出这个漏洞,运行时会出现什么问题是不确定的。 

下面是示例代码

 1    // Determine whether two strings are equal. 
 2      // If they differ in size, determine whether the smaller 
 3      // one holds the same characters as the larger one 
 4      bool str_subrange(const string &str1, const string &str2) 
 5      { 
 6          // same sizes: return normal equality test 
 7          if (str1.size() == str2.size()) 
 8              return str1 == str2;    // ok, == returns bool 
 9          // find size of smaller string 
10          string::size_type size = (str1.size() < str2.size()) 
11                                   ? str1.size() : str2.size(); 
12          string::size_type i = 0; 
13          // look at each element up to size of smaller string 
14          while (i != size) { 
15              if (str1[i] != str2[i]) 
16                  return;   // error: no return value 
17          } 
18          // error: control might flow off the end of the function without 
19 a return 
20          // the compiler is unlikely to detect this error 
21       } 

 4.const 对象、指向 const 对象的指针或引用只能用于调用其 const 成员函数,如果尝试用它们来调用非 const 成员函数,则是错误的。

 5.函数的重载与重复声明辨析:

1    // const is irrelevent for nonreference parameters
2    Record lookup(Phone); 
3    Record lookup(const Phone); // redeclaration 

《C++ Primer》中有这样两端段话:

  “最后一对的区别仅在于是否将形参定义为 const。 这种差异并不影响传递至函数的对象; 第二个函数声明被视为第一个的重复声明。 其原因在于实参传递的方式。复制形参时并不考虑形参是否为 const——函数操纵的只是副本。 函数的无法修改实参。 结果, 既可将 const 对象传递给 const 形参, 也可传递给非 const 形参,这两种形参并无本质区别。”

  “值得注意的是,形参与 const 形参的等价性仅适用于非引用形参。有 const 引用形参的函数与有非 const 引用形参的函数是不同的。类似地,如果函数带有指向 const 类型的指针形参, 则与带有指向相同类型的非 const 对象的指针形参的函数不相同。”

 参考下面代码,有利于理解上面引号中的两段话:

1       const int ival = 1024; 
2       const int &refVal = ival;      // ok: both reference and  object are 
3 const 
4       int &ref2 = ival;              // error: non const reference to a 
5 const object 

 另外,在VC++6.0中编译下段代码,编译通过,证明:const引用可以绑定到非const对象上

1     int ival = 1024; 
2     const int &refVal = ival;  

6.非 const 引用只能绑定到与该引用同类型的对象。 
const 引用则可以绑定到不同但相关的类型的对象或绑定到右值。 

原文地址:https://www.cnblogs.com/tingshuixuan2012/p/2986853.html