1.
中文版:
设置一个类型为auto的引用时,初始值中的顶层常量属性依然保留。和往常一样,如果我们给初始值绑定一个引用,则此时的常量就不是顶层常量了。”
英文版:
When we ask for a reference to an auto-deduced type, top-level consts in the initializer are not ignored. As usual, consts are not top-level when we bind a reference to an initializer
怎么理解这段话呢?能否举例说明?
天蓬老师2017-04-17 11:48:52
top-level const
: const
修飾的是自身。
low-level const
: const
修飾的是別人。
什麼叫自身,什麼叫別人? C++ 的世界:
所以,有以下幾個規律:
const
,也可以是 low-level const
。 const
。 指針何時是 top-level const
,何時是 low-level const
,請參考昨天回答的你的另一個問題。
(const char *
是 low-level, char * const
是 top-level.)
如果上面這堆概念你都搞清楚了的話,我們在來理解一下你引用的話。舉例說明:
cpp
const int ci = 0; auto &r1 = ci; // r1 is a const int&
好了,ci
是 const int
,是 top-level const
;r1
呢?是 const int&
,是引用,引用必然是 low-level const
。
所以:
consts are not top-level when we bind a reference to an initializer
後半句同意吧?
再看範例裡面的 r1
,請問你可以修改它嗎?你可能會不解,廢話,都加了 const
還能修改?
那我們來看另一個例子:
cpp
const char * ch = "test"; ch = "mood"; // ok, const is low-level char c[4] = "hel"; char * const cch = c; cch = ch; // error! const is top-level
看到了吧,對於指標來說,low-level const
是可以修改的! (對應開始的概念,指針可以是"別人",別人是 const
不影響指針指向另一個人)
那麼 const int*
可以修改,而 const int&
不能修改,這是由引用本身的概念導致的(一旦初始化無法再次綁定)。
即,const
引用是 low-level const
的同時,也兼備了 top-level const
的特質,即"自身"無法被修改。
所以:
When we ask for a reference to an auto-deduced type, top-level consts in the initializer are not ignored.
說的是“頂層常數屬性仍然保留”,好好體會一下這裡說的頂層常量屬性的含義。
綜上所述,結合我給的例子。最簡單的解釋:
auto &r1 = ci;
發生了什麼事?
const
降成 low-level const
.const
的特質(自身無法修改)依然保留。 清楚了嗎?
PS: 為什麼 C++ Primer 提倡多用引用,少用指針,因為指針太過於靈(奇)活(葩)。還是引用比較好駕馭。 。 。
大家讲道理2017-04-17 11:48:52
這方面教學很多了,我簡單寫下, 如果理解不對,歡迎指正。
#include <iostream>
using namespace std;
class MyObject{
private:
int value;
public:
MyObject(){
this->value = 0;
}
void foo() {
cout << "none const obj called" << endl; //证明调用者是一个非const对象
}
void foo() const {
cout << "const obj called" << endl; //证明调用者是一个const对象
}
MyObject (const MyObject & other){
this->value = other.value;
}
};
int main()
{
MyObject obj;
const MyObject constObj = obj;
obj.foo(); //输出非const foo
constObj.foo(); //const foo
cout<< "*******"<<endl;
auto auto_without_const = constObj; //auto没有加引用的情况下,即使右边的值有const属性,也被去了
auto_without_const.foo();
auto & auto_with_const = constObj; //一旦是引用的时候,就保留下来const属性
auto_with_const.foo();
auto & const_refer_to_none_const = obj; //右值没有const属性,初始化后也没有
const_refer_to_none_const.foo();
return 0;
}